fumadocs-openapi 5.11.8 → 6.0.0

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.
@@ -1,93 +1,214 @@
1
1
  'use client';
2
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
2
  import * as React from 'react';
4
- import { forwardRef, useId, createContext, useContext, useState, useCallback, useRef, useEffect, useMemo } from 'react';
5
- import { FormProvider, Controller, useFormContext, useFieldArray, useForm, useWatch } from 'react-hook-form';
6
- import { Collapsible, CollapsibleTrigger, CollapsibleContent } from 'fumadocs-ui/components/ui/collapsible';
3
+ import { forwardRef, createElement, useState, useMemo, useRef, useEffect, Fragment as Fragment$1 } from 'react';
4
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
5
+ import { useFormContext, Controller, useFieldArray, useForm, FormProvider } from 'react-hook-form';
7
6
  import { cn, buttonVariants } from 'fumadocs-ui/components/api';
8
- import { C as ChevronDown, a as Check, b as ChevronUp, u as useSchemaContext, T as Trash2, P as Plus, c as CircleCheck, d as CircleX, e as useApiContext, S as SchemaContext, g as getUrl } from './client-client-B06fJG48.js';
9
- import { Slot } from '@radix-ui/react-slot';
10
- import { cva } from 'class-variance-authority';
11
- import { useOnChange } from 'fumadocs-core/utils/use-on-change';
7
+ import { u as useSchemaContext, a as useApiContext, S as SchemaContext } from './client-client-CpwKrzlY.js';
12
8
  import * as SelectPrimitive from '@radix-ui/react-select';
9
+ import { cva } from 'class-variance-authority';
13
10
  import { DynamicCodeBlock } from 'fumadocs-ui/components/dynamic-codeblock';
11
+ import { S as ServerSelect } from './server-select-client-CbFencmM.js';
12
+ import { Collapsible, CollapsibleTrigger, CollapsibleContent } from 'fumadocs-ui/components/ui/collapsible';
14
13
 
15
- const Form = FormProvider;
16
- const FormFieldContext = /*#__PURE__*/ createContext({
17
- name: ''
18
- });
19
- const FormItemContext = /*#__PURE__*/ createContext({
20
- id: ''
14
+ /**
15
+ * @license lucide-react v0.474.0 - ISC
16
+ *
17
+ * This source code is licensed under the ISC license.
18
+ * See the LICENSE file in the root directory of this source tree.
19
+ */ const toKebabCase = (string)=>string.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
20
+ const mergeClasses = (...classes)=>classes.filter((className, index, array)=>{
21
+ return Boolean(className) && className.trim() !== "" && array.indexOf(className) === index;
22
+ }).join(" ").trim();
23
+
24
+ /**
25
+ * @license lucide-react v0.474.0 - ISC
26
+ *
27
+ * This source code is licensed under the ISC license.
28
+ * See the LICENSE file in the root directory of this source tree.
29
+ */ var defaultAttributes = {
30
+ xmlns: "http://www.w3.org/2000/svg",
31
+ width: 24,
32
+ height: 24,
33
+ viewBox: "0 0 24 24",
34
+ fill: "none",
35
+ stroke: "currentColor",
36
+ strokeWidth: 2,
37
+ strokeLinecap: "round",
38
+ strokeLinejoin: "round"
39
+ };
40
+
41
+ const Icon = /*#__PURE__*/ forwardRef(({ color = "currentColor", size = 24, strokeWidth = 2, absoluteStrokeWidth, className = "", children, iconNode, ...rest }, ref)=>{
42
+ return /*#__PURE__*/ createElement("svg", {
43
+ ref,
44
+ ...defaultAttributes,
45
+ width: size,
46
+ height: size,
47
+ stroke: color,
48
+ strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,
49
+ className: mergeClasses("lucide", className),
50
+ ...rest
51
+ }, [
52
+ ...iconNode.map(([tag, attrs])=>/*#__PURE__*/ createElement(tag, attrs)),
53
+ ...Array.isArray(children) ? children : [
54
+ children
55
+ ]
56
+ ]);
21
57
  });
22
- function FormField({ ...props }) {
23
- return /*#__PURE__*/ jsx(FormFieldContext.Provider, {
24
- value: {
25
- name: props.name
26
- },
27
- children: /*#__PURE__*/ jsx(Controller, {
28
- ...props
29
- })
30
- });
31
- }
32
- function useFormField() {
33
- const fieldContext = useContext(FormFieldContext);
34
- const { id } = useContext(FormItemContext);
35
- const { getFieldState, formState } = useFormContext();
36
- const fieldState = getFieldState(fieldContext.name, formState);
37
- return {
38
- id,
39
- name: fieldContext.name,
40
- formItemId: `${id}-form-item`,
41
- formDescriptionId: `${id}-form-item-description`,
42
- isError: Boolean(fieldState.error)
43
- };
44
- }
45
- const FormItem = /*#__PURE__*/ forwardRef(({ className, ...props }, ref)=>{
46
- const id = useId();
47
- return /*#__PURE__*/ jsx(FormItemContext.Provider, {
48
- value: {
49
- id
50
- },
51
- children: /*#__PURE__*/ jsx("div", {
52
- ref: ref,
53
- className: cn('flex flex-col gap-1', className),
58
+
59
+ const createLucideIcon = (iconName, iconNode)=>{
60
+ const Component = /*#__PURE__*/ forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ createElement(Icon, {
61
+ ref,
62
+ iconNode,
63
+ className: mergeClasses(`lucide-${toKebabCase(iconName)}`, className),
54
64
  ...props
55
- })
56
- });
57
- });
58
- FormItem.displayName = 'FormItem';
59
- const labelVariants = cva('font-mono text-xs text-fd-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-70');
60
- const FormLabel = /*#__PURE__*/ forwardRef(({ className, ...props }, ref)=>{
61
- const { isError, formItemId } = useFormField();
62
- return /*#__PURE__*/ jsx("label", {
63
- ref: ref,
64
- className: cn(labelVariants(), isError && 'text-red-500', className),
65
- htmlFor: formItemId,
66
- ...props
67
- });
68
- });
69
- FormLabel.displayName = 'FormLabel';
70
- const FormControl = /*#__PURE__*/ forwardRef(({ ...props }, ref)=>{
71
- const { isError, formItemId, formDescriptionId } = useFormField();
72
- return /*#__PURE__*/ jsx(Slot, {
73
- ref: ref,
74
- id: formItemId,
75
- "aria-describedby": formDescriptionId,
76
- "aria-invalid": isError,
77
- ...props
78
- });
79
- });
80
- FormControl.displayName = 'FormControl';
81
- const FormDescription = /*#__PURE__*/ forwardRef(({ className, ...props }, ref)=>{
82
- const { formDescriptionId } = useFormField();
83
- return /*#__PURE__*/ jsx("p", {
84
- ref: ref,
85
- id: formDescriptionId,
86
- className: cn('text-xs text-fd-muted-foreground', className),
87
- ...props
88
- });
89
- });
90
- FormDescription.displayName = 'FormDescription';
65
+ }));
66
+ Component.displayName = `${iconName}`;
67
+ return Component;
68
+ };
69
+
70
+ const __iconNode$6 = [
71
+ [
72
+ "path",
73
+ {
74
+ d: "M20 6 9 17l-5-5",
75
+ key: "1gmf2c"
76
+ }
77
+ ]
78
+ ];
79
+ const Check = createLucideIcon("Check", __iconNode$6);
80
+
81
+ const __iconNode$5 = [
82
+ [
83
+ "path",
84
+ {
85
+ d: "m6 9 6 6 6-6",
86
+ key: "qrunsl"
87
+ }
88
+ ]
89
+ ];
90
+ const ChevronDown = createLucideIcon("ChevronDown", __iconNode$5);
91
+
92
+ const __iconNode$4 = [
93
+ [
94
+ "path",
95
+ {
96
+ d: "m18 15-6-6-6 6",
97
+ key: "153udz"
98
+ }
99
+ ]
100
+ ];
101
+ const ChevronUp = createLucideIcon("ChevronUp", __iconNode$4);
102
+
103
+ const __iconNode$3 = [
104
+ [
105
+ "circle",
106
+ {
107
+ cx: "12",
108
+ cy: "12",
109
+ r: "10",
110
+ key: "1mglay"
111
+ }
112
+ ],
113
+ [
114
+ "path",
115
+ {
116
+ d: "m9 12 2 2 4-4",
117
+ key: "dzmm74"
118
+ }
119
+ ]
120
+ ];
121
+ const CircleCheck = createLucideIcon("CircleCheck", __iconNode$3);
122
+
123
+ const __iconNode$2 = [
124
+ [
125
+ "circle",
126
+ {
127
+ cx: "12",
128
+ cy: "12",
129
+ r: "10",
130
+ key: "1mglay"
131
+ }
132
+ ],
133
+ [
134
+ "path",
135
+ {
136
+ d: "m15 9-6 6",
137
+ key: "1uzhvr"
138
+ }
139
+ ],
140
+ [
141
+ "path",
142
+ {
143
+ d: "m9 9 6 6",
144
+ key: "z0biqf"
145
+ }
146
+ ]
147
+ ];
148
+ const CircleX = createLucideIcon("CircleX", __iconNode$2);
149
+
150
+ const __iconNode$1 = [
151
+ [
152
+ "path",
153
+ {
154
+ d: "M5 12h14",
155
+ key: "1ays0h"
156
+ }
157
+ ],
158
+ [
159
+ "path",
160
+ {
161
+ d: "M12 5v14",
162
+ key: "s699le"
163
+ }
164
+ ]
165
+ ];
166
+ const Plus = createLucideIcon("Plus", __iconNode$1);
167
+
168
+ const __iconNode = [
169
+ [
170
+ "path",
171
+ {
172
+ d: "M3 6h18",
173
+ key: "d0wm0j"
174
+ }
175
+ ],
176
+ [
177
+ "path",
178
+ {
179
+ d: "M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6",
180
+ key: "4alrt4"
181
+ }
182
+ ],
183
+ [
184
+ "path",
185
+ {
186
+ d: "M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2",
187
+ key: "v07s0e"
188
+ }
189
+ ],
190
+ [
191
+ "line",
192
+ {
193
+ x1: "10",
194
+ x2: "10",
195
+ y1: "11",
196
+ y2: "17",
197
+ key: "1uufr5"
198
+ }
199
+ ],
200
+ [
201
+ "line",
202
+ {
203
+ x1: "14",
204
+ x2: "14",
205
+ y1: "11",
206
+ y2: "17",
207
+ key: "xtxkd"
208
+ }
209
+ ]
210
+ ];
211
+ const Trash2 = createLucideIcon("Trash2", __iconNode);
91
212
 
92
213
  /**
93
214
  * Resolve reference
@@ -127,7 +248,7 @@ const Select = SelectPrimitive.Root;
127
248
  const SelectValue = SelectPrimitive.Value;
128
249
  const SelectTrigger = /*#__PURE__*/ forwardRef(({ className, children, ...props }, ref)=>/*#__PURE__*/ jsxs(SelectPrimitive.Trigger, {
129
250
  ref: ref,
130
- className: cn('flex h-10 items-center rounded-md border px-3 py-2 text-start text-sm text-fd-foreground hover:bg-fd-accent focus:outline-none focus:ring-2 focus:ring-fd-ring disabled:cursor-not-allowed disabled:opacity-50', className),
251
+ className: cn('flex h-10 items-center w-full rounded-md border px-3 py-2 text-start text-[13px] text-fd-foreground hover:bg-fd-accent focus:outline-none focus:ring-2 focus:ring-fd-ring disabled:cursor-not-allowed disabled:opacity-50', className),
131
252
  ...props,
132
253
  children: [
133
254
  children,
@@ -158,16 +279,16 @@ const SelectScrollDownButton = /*#__PURE__*/ forwardRef(({ className, ...props }
158
279
  })
159
280
  }));
160
281
  SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
161
- const SelectContent = /*#__PURE__*/ forwardRef(({ className, children, position = 'popper', ...props }, ref)=>/*#__PURE__*/ jsx(SelectPrimitive.Portal, {
282
+ const SelectContent = /*#__PURE__*/ forwardRef(({ className, children, position, ...props }, ref)=>/*#__PURE__*/ jsx(SelectPrimitive.Portal, {
162
283
  children: /*#__PURE__*/ jsxs(SelectPrimitive.Content, {
163
284
  ref: ref,
164
- className: cn('z-50 overflow-hidden rounded-lg border bg-fd-popover text-fd-popover-foreground shadow-md data-[state=closed]:animate-fd-popover-out data-[state=open]:animate-fd-popover-in', className),
285
+ className: cn('z-50 overflow-hidden rounded-lg border bg-fd-popover text-fd-popover-foreground shadow-md', className),
165
286
  position: position,
166
287
  ...props,
167
288
  children: [
168
289
  /*#__PURE__*/ jsx(SelectScrollUpButton, {}),
169
290
  /*#__PURE__*/ jsx(SelectPrimitive.Viewport, {
170
- className: cn('p-1', position === 'popper' && 'h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]'),
291
+ className: "p-1",
171
292
  children: children
172
293
  }),
173
294
  /*#__PURE__*/ jsx(SelectScrollDownButton, {})
@@ -183,7 +304,7 @@ const SelectLabel = /*#__PURE__*/ forwardRef(({ className, ...props }, ref)=>/*#
183
304
  SelectLabel.displayName = SelectPrimitive.Label.displayName;
184
305
  const SelectItem = /*#__PURE__*/ forwardRef(({ className, children, ...props }, ref)=>/*#__PURE__*/ jsxs(SelectPrimitive.Item, {
185
306
  ref: ref,
186
- className: cn('flex select-none flex-row items-center rounded-md py-1.5 pe-2 ps-6 text-sm outline-none focus:bg-fd-accent focus:text-fd-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50', className),
307
+ className: cn('flex select-none flex-row items-center rounded-md py-1.5 pe-2 ps-6 text-[13px] outline-none focus:bg-fd-accent focus:text-fd-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50', className),
187
308
  ...props,
188
309
  children: [
189
310
  /*#__PURE__*/ jsx(SelectPrimitive.ItemIndicator, {
@@ -205,64 +326,36 @@ const SelectSeparator = /*#__PURE__*/ forwardRef(({ className, ...props }, ref)=
205
326
  }));
206
327
  SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
207
328
 
329
+ const labelVariants = cva('text-[13px] font-mono text-fd-card-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-70');
208
330
  const Input = /*#__PURE__*/ React.forwardRef(({ className, type, ...props }, ref)=>{
209
331
  return /*#__PURE__*/ jsx("input", {
210
332
  type: type,
211
- className: cn('flex h-9 w-full rounded-md border bg-transparent px-2 py-1.5 text-sm text-fd-foreground transition-colors placeholder:text-fd-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-fd-ring disabled:cursor-not-allowed disabled:opacity-50', className),
333
+ className: cn('flex h-9 w-full rounded-md border bg-transparent px-2 py-1.5 text-[13px] text-fd-foreground transition-colors placeholder:text-fd-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-fd-ring disabled:cursor-not-allowed disabled:opacity-50', className),
212
334
  ref: ref,
213
335
  ...props
214
336
  });
215
337
  });
216
338
  Input.displayName = 'Input';
217
339
 
218
- function renderInner({ field, ...props }) {
219
- if (field.type === 'object') return /*#__PURE__*/ jsx(ObjectInput, {
220
- field: field,
340
+ function FieldHeader({ name, required = false, type, ...props }) {
341
+ return /*#__PURE__*/ jsxs("label", {
221
342
  ...props,
222
- className: cn('rounded-lg border bg-fd-accent/20 p-3', props.className)
223
- });
224
- if (field.type === 'switcher') return /*#__PURE__*/ jsx(Switcher, {
225
- inline: true,
226
- field: field,
227
- ...props
228
- });
229
- if (field.type === 'array') return /*#__PURE__*/ jsx(ArrayInput, {
230
- field: field,
231
- ...props,
232
- className: cn('rounded-lg border bg-fd-background p-3', props.className)
233
- });
234
- if (field.type === 'null') return null;
235
- return /*#__PURE__*/ jsx(NormalInput, {
236
- field: field,
237
- ...props
238
- });
239
- }
240
- function InputContainer({ toolbar, name, required, type, description, inline = false, ...props }) {
241
- return /*#__PURE__*/ jsxs("div", {
242
- ...props,
243
- className: cn('flex flex-col gap-1', props.className),
343
+ className: cn('w-full inline-flex items-center gap-1', props.className),
244
344
  children: [
245
- /*#__PURE__*/ jsxs("div", {
246
- className: cn(labelVariants(), 'inline-flex items-center gap-1'),
247
- children: [
248
- name,
249
- required ? /*#__PURE__*/ jsx("span", {
250
- className: "text-red-500",
251
- children: "*"
252
- }) : null,
253
- /*#__PURE__*/ jsx("div", {
254
- className: "flex-1"
255
- }),
256
- type ? /*#__PURE__*/ jsx("code", {
257
- className: "text-xs text-fd-muted-foreground",
258
- children: type
259
- }) : null,
260
- toolbar
261
- ]
345
+ /*#__PURE__*/ jsx("span", {
346
+ className: cn(labelVariants()),
347
+ children: name
262
348
  }),
263
- !inline ? /*#__PURE__*/ jsx("p", {
264
- className: "text-xs",
265
- children: description
349
+ required ? /*#__PURE__*/ jsx("span", {
350
+ className: "text-red-500",
351
+ children: "*"
352
+ }) : null,
353
+ /*#__PURE__*/ jsx("div", {
354
+ className: "flex-1"
355
+ }),
356
+ type ? /*#__PURE__*/ jsx("code", {
357
+ className: "text-xs text-fd-muted-foreground",
358
+ children: type
266
359
  }) : null,
267
360
  props.children
268
361
  ]
@@ -272,9 +365,9 @@ function ObjectInput({ field, fieldName, ...props }) {
272
365
  const { references } = useSchemaContext();
273
366
  return /*#__PURE__*/ jsxs("div", {
274
367
  ...props,
275
- className: cn('flex flex-col gap-4', props.className),
368
+ className: cn('flex flex-col gap-6', props.className),
276
369
  children: [
277
- Object.entries(field.properties).map(([key, child])=>/*#__PURE__*/ jsx(InputField, {
370
+ Object.entries(field.properties).map(([key, child])=>/*#__PURE__*/ jsx(FieldSet, {
278
371
  name: key,
279
372
  field: resolve(child, references),
280
373
  fieldName: `${fieldName}.${key}`
@@ -295,13 +388,11 @@ function AdditionalProperties({ fieldName, type }) {
295
388
  if (d?.type === 'object') return d.properties;
296
389
  return [];
297
390
  });
298
- useOnChange(properties, ()=>{
299
- dynamic.current.set(`additional_${fieldName}`, {
300
- type: 'object',
301
- properties
302
- });
391
+ dynamic.current.set(`additional_${fieldName}`, {
392
+ type: 'object',
393
+ properties
303
394
  });
304
- const onAppend = useCallback(()=>{
395
+ const onAppend = ()=>{
305
396
  const name = nextName.trim();
306
397
  if (name.length === 0) return;
307
398
  setProperties((p)=>{
@@ -313,15 +404,11 @@ function AdditionalProperties({ fieldName, type }) {
313
404
  name
314
405
  ];
315
406
  });
316
- }, [
317
- nextName,
318
- setValue,
319
- fieldName
320
- ]);
407
+ };
321
408
  const types = typeof type === 'string' ? resolveDynamicTypes(references[type], references) : undefined;
322
409
  return /*#__PURE__*/ jsxs(Fragment, {
323
410
  children: [
324
- properties.map((item)=>/*#__PURE__*/ jsx(Switcher, {
411
+ properties.map((item)=>/*#__PURE__*/ jsx(FieldSet, {
325
412
  name: item,
326
413
  field: {
327
414
  type: 'switcher',
@@ -351,17 +438,15 @@ function AdditionalProperties({ fieldName, type }) {
351
438
  /*#__PURE__*/ jsx(Input, {
352
439
  value: nextName,
353
440
  placeholder: "Enter Property Name",
354
- onChange: useCallback((e)=>{
441
+ onChange: (e)=>{
355
442
  setNextName(e.target.value);
356
- }, []),
357
- onKeyDown: useCallback((e)=>{
443
+ },
444
+ onKeyDown: (e)=>{
358
445
  if (e.key === 'Enter') {
359
446
  onAppend();
360
447
  e.preventDefault();
361
448
  }
362
- }, [
363
- onAppend
364
- ])
449
+ }
365
450
  }),
366
451
  /*#__PURE__*/ jsx("button", {
367
452
  type: "button",
@@ -417,11 +502,84 @@ anyFields.array = {
417
502
  items: anyFields
418
503
  }
419
504
  };
420
- function Switcher({ field, fieldName, ...props }) {
505
+ function FieldInput({ field, fieldName, ...props }) {
506
+ const { control, register } = useFormContext();
507
+ if (field.type === 'null') return null;
508
+ if (field.type === 'object') {
509
+ return /*#__PURE__*/ jsx(ObjectInput, {
510
+ field: field,
511
+ fieldName: fieldName,
512
+ ...props,
513
+ className: cn('rounded-lg border border-fd-primary/20 bg-fd-card p-3 shadow-sm', props.className)
514
+ });
515
+ }
516
+ if (field.type === 'array') {
517
+ return /*#__PURE__*/ jsx(ArrayInput, {
518
+ fieldName: fieldName,
519
+ field: field,
520
+ ...props,
521
+ className: cn('rounded-lg border border-fd-primary/20 bg-fd-background p-3 shadow-sm', props.className)
522
+ });
523
+ }
524
+ if (field.type === 'file' || field.type === 'boolean') {
525
+ return /*#__PURE__*/ jsx(Controller, {
526
+ control: control,
527
+ name: fieldName,
528
+ render: ({ field: { value, onChange, ...restField } })=>field.type === 'file' ? /*#__PURE__*/ jsx("input", {
529
+ id: fieldName,
530
+ type: "file",
531
+ multiple: false,
532
+ onChange: (e)=>{
533
+ if (!e.target.files) return;
534
+ onChange(e.target.files.item(0));
535
+ },
536
+ ...props,
537
+ ...restField
538
+ }) : /*#__PURE__*/ jsxs(Select, {
539
+ value: value,
540
+ onValueChange: onChange,
541
+ disabled: restField.disabled,
542
+ children: [
543
+ /*#__PURE__*/ jsx(SelectTrigger, {
544
+ id: fieldName,
545
+ className: props.className,
546
+ ...restField,
547
+ children: /*#__PURE__*/ jsx(SelectValue, {})
548
+ }),
549
+ /*#__PURE__*/ jsxs(SelectContent, {
550
+ children: [
551
+ /*#__PURE__*/ jsx(SelectItem, {
552
+ value: "true",
553
+ children: "True"
554
+ }),
555
+ /*#__PURE__*/ jsx(SelectItem, {
556
+ value: "false",
557
+ children: "False"
558
+ }),
559
+ field.isRequired ? null : /*#__PURE__*/ jsx(SelectItem, {
560
+ value: "null",
561
+ children: "Null"
562
+ })
563
+ ]
564
+ })
565
+ ]
566
+ })
567
+ });
568
+ }
569
+ return /*#__PURE__*/ jsx(Input, {
570
+ id: fieldName,
571
+ placeholder: "Enter value",
572
+ type: field.type === 'string' ? 'text' : 'number',
573
+ ...register(fieldName),
574
+ ...props
575
+ });
576
+ }
577
+ function FieldSet({ field, fieldName, toolbar, name, ...props }) {
421
578
  const { references, dynamic } = useSchemaContext();
422
- const items = Object.keys(field.items);
423
579
  const [value, setValue] = useState(()=>{
580
+ if (field.type !== 'switcher') return '';
424
581
  const d = dynamic.current.get(fieldName);
582
+ const items = Object.keys(field.items);
425
583
  if (d?.type === 'field') {
426
584
  // schemas are passed from server components, they shouldn't be re-constructed
427
585
  const cached = items.find((item)=>d.schema === field.items[item]);
@@ -429,193 +587,66 @@ function Switcher({ field, fieldName, ...props }) {
429
587
  }
430
588
  return items[0];
431
589
  });
432
- useOnChange(value, ()=>{
433
- if (!value) return;
590
+ if (field.type === 'null') return null;
591
+ if (value && field.type === 'switcher') {
434
592
  dynamic.current.set(fieldName, {
435
593
  type: 'field',
436
594
  schema: field.items[value]
437
595
  });
438
- });
439
- return /*#__PURE__*/ jsx(InputContainer, {
440
- required: field.isRequired,
441
- description: field.description,
442
- ...props,
443
- toolbar: /*#__PURE__*/ jsxs(Fragment, {
596
+ }
597
+ if (field.type === 'switcher') {
598
+ const child = resolve(field.items[value], references);
599
+ return /*#__PURE__*/ jsxs("fieldset", {
600
+ ...props,
601
+ className: cn('flex flex-col gap-1.5', props.className),
444
602
  children: [
445
- /*#__PURE__*/ jsxs(Select, {
446
- value: value,
447
- onValueChange: setValue,
603
+ /*#__PURE__*/ jsxs(FieldHeader, {
604
+ name: name,
605
+ htmlFor: fieldName,
606
+ required: field.isRequired,
448
607
  children: [
449
- /*#__PURE__*/ jsx(SelectTrigger, {
450
- className: "h-auto p-1 text-xs",
451
- children: /*#__PURE__*/ jsx(SelectValue, {})
452
- }),
453
- /*#__PURE__*/ jsx(SelectContent, {
454
- children: items.map((item)=>/*#__PURE__*/ jsx(SelectItem, {
608
+ /*#__PURE__*/ jsx("select", {
609
+ value: value,
610
+ onChange: (e)=>setValue(e.target.value),
611
+ className: "text-xs",
612
+ children: Object.keys(field.items).map((item)=>/*#__PURE__*/ jsx("option", {
455
613
  value: item,
456
614
  children: item
457
615
  }, item))
458
- })
459
- ]
460
- }),
461
- props.toolbar
462
- ]
463
- }),
464
- children: renderInner({
465
- field: resolve(field.items[value], references),
466
- fieldName
467
- })
468
- });
469
- }
470
- function InputField({ field, fieldName, ...props }) {
471
- const { references } = useSchemaContext();
472
- if (field.type === 'null') return null;
473
- if (field.type === 'object') {
474
- return /*#__PURE__*/ jsx(InputContainer, {
475
- required: field.isRequired,
476
- type: field.type,
477
- description: field.description,
478
- ...props,
479
- children: /*#__PURE__*/ jsx(ObjectInput, {
480
- field: field,
481
- fieldName: fieldName,
482
- className: "rounded-lg border bg-fd-accent/20 p-3"
483
- })
484
- });
485
- }
486
- if (field.type === 'array') {
487
- return /*#__PURE__*/ jsx(InputContainer, {
488
- required: field.isRequired,
489
- description: field.description ?? resolve(field.items, references).description,
490
- type: "array",
491
- ...props,
492
- children: /*#__PURE__*/ jsx(ArrayInput, {
493
- fieldName: fieldName,
494
- field: field,
495
- className: "rounded-lg border bg-fd-background p-3"
496
- })
497
- });
498
- }
499
- if (field.type === 'switcher') {
500
- return /*#__PURE__*/ jsx(Switcher, {
501
- field: field,
502
- fieldName: fieldName,
503
- ...props
504
- });
505
- }
506
- const { toolbar, inline = false, name, ...rest } = props;
507
- return /*#__PURE__*/ jsx(NormalInput, {
508
- field: field,
509
- fieldName: fieldName,
510
- header: /*#__PURE__*/ jsxs(Fragment, {
511
- children: [
512
- /*#__PURE__*/ jsxs(FormLabel, {
513
- className: "inline-flex items-center gap-1",
514
- children: [
515
- name,
516
- field.isRequired ? /*#__PURE__*/ jsx("span", {
517
- className: "text-red-500",
518
- children: "*"
519
- }) : null,
520
- /*#__PURE__*/ jsx("code", {
521
- className: "ms-auto text-xs text-fd-muted-foreground",
522
- children: field.type
523
616
  }),
524
617
  toolbar
525
618
  ]
526
619
  }),
527
- !inline ? /*#__PURE__*/ jsx(FormDescription, {
528
- className: "text-xs",
620
+ /*#__PURE__*/ jsx("p", {
621
+ className: "text-xs text-fd-muted-foreground",
529
622
  children: field.description
530
- }) : null
531
- ]
532
- }),
533
- ...rest
534
- });
535
- }
536
- function NormalInput({ fieldName, header, field, ...props }) {
537
- const { control } = useFormContext();
538
- if (field.type === 'file') {
539
- return /*#__PURE__*/ jsx(FormField, {
540
- control: control,
541
- name: fieldName,
542
- render: ({ field: { value: _value, onChange, ...restField } })=>/*#__PURE__*/ jsxs(FormItem, {
543
- ...props,
544
- children: [
545
- header,
546
- /*#__PURE__*/ jsx(FormControl, {
547
- children: /*#__PURE__*/ jsx("input", {
548
- type: "file",
549
- multiple: false,
550
- onChange: (e)=>{
551
- if (!e.target.files) return;
552
- onChange(e.target.files.item(0));
553
- },
554
- ...restField
555
- })
556
- })
557
- ]
558
- })
559
- });
560
- }
561
- if (field.type === 'boolean') {
562
- return /*#__PURE__*/ jsx(FormField, {
563
- control: control,
564
- name: fieldName,
565
- render: ({ field: { value, onChange, ...restField } })=>/*#__PURE__*/ jsxs(FormItem, {
566
- ...props,
567
- children: [
568
- header,
569
- /*#__PURE__*/ jsxs(Select, {
570
- value: value,
571
- onValueChange: onChange,
572
- disabled: restField.disabled,
573
- children: [
574
- /*#__PURE__*/ jsx(FormControl, {
575
- children: /*#__PURE__*/ jsx(SelectTrigger, {
576
- ...restField,
577
- children: /*#__PURE__*/ jsx(SelectValue, {})
578
- })
579
- }),
580
- /*#__PURE__*/ jsxs(SelectContent, {
581
- children: [
582
- /*#__PURE__*/ jsx(SelectItem, {
583
- value: "true",
584
- children: "True"
585
- }),
586
- /*#__PURE__*/ jsx(SelectItem, {
587
- value: "false",
588
- children: "False"
589
- }),
590
- field.isRequired ? null : /*#__PURE__*/ jsx(SelectItem, {
591
- value: "null",
592
- children: "Null"
593
- })
594
- ]
595
- })
596
- ]
597
- })
598
- ]
623
+ }),
624
+ child.type === 'switcher' ? /*#__PURE__*/ jsx(FieldSet, {
625
+ field: child,
626
+ fieldName: fieldName
627
+ }) : /*#__PURE__*/ jsx(FieldInput, {
628
+ field: child,
629
+ fieldName: fieldName
599
630
  })
631
+ ]
600
632
  });
601
633
  }
602
- return /*#__PURE__*/ jsx(FormField, {
603
- control: control,
604
- name: fieldName,
605
- render: ({ field: { value, ...restField } })=>/*#__PURE__*/ jsxs(FormItem, {
606
- ...props,
607
- children: [
608
- header,
609
- /*#__PURE__*/ jsx(FormControl, {
610
- children: /*#__PURE__*/ jsx(Input, {
611
- placeholder: "Enter value",
612
- type: field.type === 'string' ? 'text' : 'number',
613
- value: value,
614
- ...restField
615
- })
616
- })
617
- ]
634
+ return /*#__PURE__*/ jsxs("fieldset", {
635
+ ...props,
636
+ className: cn('flex flex-col gap-1.5', props.className),
637
+ children: [
638
+ /*#__PURE__*/ jsx(FieldHeader, {
639
+ htmlFor: fieldName,
640
+ name: name,
641
+ required: field.isRequired,
642
+ type: field.type,
643
+ children: toolbar
644
+ }),
645
+ /*#__PURE__*/ jsx(FieldInput, {
646
+ field: field,
647
+ fieldName: fieldName
618
648
  })
649
+ ]
619
650
  });
620
651
  }
621
652
  function ArrayInput({ fieldName, field, ...props }) {
@@ -624,23 +655,14 @@ function ArrayInput({ fieldName, field, ...props }) {
624
655
  const { fields, append, remove } = useFieldArray({
625
656
  name: fieldName
626
657
  });
627
- const handleAppend = useCallback(()=>{
628
- append(getDefaultValue(items, references));
629
- }, [
630
- append,
631
- references,
632
- items
633
- ]);
634
658
  return /*#__PURE__*/ jsxs("div", {
635
659
  ...props,
636
- className: cn('flex flex-col gap-4', props.className),
660
+ className: cn('flex flex-col gap-2', props.className),
637
661
  children: [
638
- fields.map((item, index)=>/*#__PURE__*/ jsx(InputField, {
639
- inline: true,
640
- name: `Item ${String(index + 1)}`,
662
+ fields.map((item, index)=>/*#__PURE__*/ jsx(FieldSet, {
663
+ name: `${fieldName.split('.').at(-1)}[${index}]`,
641
664
  field: items,
642
- fieldName: `${fieldName}.${String(index)}`,
643
- className: "flex-1",
665
+ fieldName: `${fieldName}.${index}`,
644
666
  toolbar: /*#__PURE__*/ jsx("button", {
645
667
  type: "button",
646
668
  "aria-label": "Remove Item",
@@ -659,10 +681,13 @@ function ArrayInput({ fieldName, field, ...props }) {
659
681
  /*#__PURE__*/ jsxs("button", {
660
682
  type: "button",
661
683
  className: cn(buttonVariants({
662
- color: 'secondary',
663
- className: 'gap-1.5'
684
+ color: 'outline',
685
+ className: 'gap-1.5 py-2',
686
+ size: 'sm'
664
687
  })),
665
- onClick: handleAppend,
688
+ onClick: ()=>{
689
+ append(getDefaultValue(items, references));
690
+ },
666
691
  children: [
667
692
  /*#__PURE__*/ jsx(Plus, {
668
693
  className: "size-4"
@@ -726,12 +751,88 @@ function getStatusInfo(status) {
726
751
  };
727
752
  }
728
753
 
754
+ function getUrl(url, variables) {
755
+ let out = url;
756
+ for (const [key, value] of Object.entries(variables)){
757
+ out = out.replaceAll(`{${key}}`, value);
758
+ }
759
+ return out;
760
+ }
761
+
762
+ const variants = cva('font-mono font-medium', {
763
+ variants: {
764
+ color: {
765
+ green: 'text-green-600 dark:text-green-400',
766
+ yellow: 'text-yellow-600 dark:text-yellow-400',
767
+ red: 'text-red-600 dark:text-red-400',
768
+ blue: 'text-blue-600 dark:text-blue-400',
769
+ orange: 'text-orange-600 dark:text-orange-400'
770
+ }
771
+ }
772
+ });
773
+ function getBadgeColor(method) {
774
+ switch(method.toUpperCase()){
775
+ case 'PUT':
776
+ return 'yellow';
777
+ case 'PATCH':
778
+ return 'orange';
779
+ case 'POST':
780
+ return 'blue';
781
+ case 'DELETE':
782
+ return 'red';
783
+ default:
784
+ return 'green';
785
+ }
786
+ }
787
+ function MethodLabel({ children, ...props }) {
788
+ return /*#__PURE__*/ jsx("span", {
789
+ ...props,
790
+ className: cn(variants({
791
+ color: getBadgeColor(children)
792
+ }), props.className),
793
+ children: children.toUpperCase()
794
+ });
795
+ }
796
+
797
+ function useQuery(fn) {
798
+ const [loading, setLoading] = useState(false);
799
+ const [data, setData] = useState();
800
+ return useMemo(()=>({
801
+ isLoading: loading,
802
+ data,
803
+ start (input) {
804
+ setLoading(true);
805
+ void fn(input).then((res)=>{
806
+ setData(res);
807
+ }).catch(()=>{
808
+ setData(undefined);
809
+ }).finally(()=>{
810
+ setLoading(false);
811
+ });
812
+ }
813
+ }), [
814
+ data,
815
+ fn,
816
+ loading
817
+ ]);
818
+ }
819
+
820
+ function defaultAuthValue(auth) {
821
+ if (!auth || auth.type === 'apiKey') return '';
822
+ if (auth.type === 'http' && auth.scheme === 'basic') {
823
+ return {
824
+ username: '',
825
+ password: ''
826
+ };
827
+ }
828
+ return 'Bearer';
829
+ }
729
830
  function APIPlayground({ route, method = 'GET', authorization, path = [], header = [], query = [], body, fields = {}, schemas, proxyUrl, components: { ResultDisplay = DefaultResultDisplay } = {}, ...props }) {
730
831
  const { serverRef } = useApiContext();
731
832
  const dynamicRef = useRef(new Map());
732
833
  const form = useForm({
733
834
  defaultValues: {
734
- authorization: authorization?.defaultValue,
835
+ authorization: defaultAuthValue(authorization),
735
836
  path: getDefaultValues(path, schemas),
736
837
  query: getDefaultValues(query, schemas),
737
838
  header: getDefaultValues(header, schemas),
@@ -739,20 +840,42 @@ function APIPlayground({ route, method = 'GET', authorization, path = [], header
739
840
  }
740
841
  });
741
842
  const testQuery = useQuery(async (input)=>{
742
- const fetcher = await import('./fetcher-Cc3BieIx.js').then((mod)=>mod.createBrowserFetcher(body, schemas));
843
+ const fetcher = await import('./fetcher-Cey1qI8X.js').then((mod)=>mod.createBrowserFetcher(body, schemas));
844
+ const query = {
845
+ ...input.query
846
+ };
847
+ const header = {
848
+ ...input.header
849
+ };
850
+ if (input.authorization && authorization) {
851
+ if (authorization.type === 'apiKey') {
852
+ if (authorization.in === 'header') {
853
+ header[authorization.name] = input.authorization;
854
+ } else if (authorization.in === 'query') {
855
+ query[authorization.name] = input.authorization;
856
+ } else {
857
+ if ('cookie' in header) {
858
+ header.Cookie = header.cookie;
859
+ delete header.cookie;
860
+ }
861
+ header.Cookie = [
862
+ header.Cookie,
863
+ `${authorization.name}=${input.authorization}`
864
+ ].filter((s)=>s.length > 0).join('; ');
865
+ }
866
+ } else if (authorization.type === 'http' && authorization.scheme === 'basic') {
867
+ if (typeof input.authorization === 'object') header.Authorization = `Basic ${btoa(`${input.authorization.username}:${input.authorization.password}`)}`;
868
+ } else {
869
+ header.Authorization = input.authorization;
870
+ }
871
+ }
743
872
  const serverUrl = serverRef.current ? getUrl(serverRef.current.url, serverRef.current.variables) : window.location.origin;
744
- let url = `${serverUrl}${createPathnameFromInput(route, input.path, input.query)}`;
873
+ let url = `${serverUrl}${createPathnameFromInput(route, input.path, query)}`;
745
874
  if (proxyUrl) {
746
875
  const updated = new URL(proxyUrl, window.location.origin);
747
876
  updated.searchParams.append('url', url);
748
877
  url = updated.toString();
749
878
  }
750
- const header = {
751
- ...input.header
752
- };
753
- if (input.authorization && authorization) {
754
- header[authorization.name] = input.authorization;
755
- }
756
879
  return fetcher.fetch({
757
880
  url: url.toString(),
758
881
  header,
@@ -766,12 +889,12 @@ function APIPlayground({ route, method = 'GET', authorization, path = [], header
766
889
  });
767
890
  useEffect(()=>{
768
891
  if (!authorization) return;
769
- const key = `__fumadocs_authorization_${authorization.authType}`;
892
+ const key = `__fumadocs_auth_${JSON.stringify(authorization)}`;
770
893
  const cached = localStorage.getItem(key);
771
- if (cached) form.setValue('authorization', cached);
894
+ if (cached) form.setValue('authorization', JSON.parse(cached));
772
895
  const subscription = form.watch((value, { name })=>{
773
- if (name !== 'authorization' || !value.authorization) return;
774
- localStorage.setItem(key, value.authorization);
896
+ if (!name || !name.startsWith('authorization') || !value.authorization) return;
897
+ localStorage.setItem(key, JSON.stringify(value.authorization));
775
898
  });
776
899
  return ()=>{
777
900
  subscription.unsubscribe();
@@ -792,13 +915,13 @@ function APIPlayground({ route, method = 'GET', authorization, path = [], header
792
915
  name: fieldName
793
916
  }, key);
794
917
  }
795
- return /*#__PURE__*/ jsx(InputField, {
918
+ return /*#__PURE__*/ jsx(FieldSet, {
796
919
  name: info.name,
797
920
  fieldName: fieldName,
798
921
  field: info
799
922
  }, key);
800
923
  }
801
- return /*#__PURE__*/ jsx(Form, {
924
+ return /*#__PURE__*/ jsx(FormProvider, {
802
925
  ...form,
803
926
  children: /*#__PURE__*/ jsx(SchemaContext.Provider, {
804
927
  value: useMemo(()=>({
@@ -809,26 +932,47 @@ function APIPlayground({ route, method = 'GET', authorization, path = [], header
809
932
  ]),
810
933
  children: /*#__PURE__*/ jsxs("form", {
811
934
  ...props,
812
- className: cn('not-prose flex flex-col gap-5 rounded-xl border bg-fd-card p-3', props.className),
935
+ className: cn('not-prose flex flex-col gap-2 rounded-xl border p-3 shadow-md', props.className),
813
936
  onSubmit: onSubmit,
814
937
  children: [
815
- /*#__PURE__*/ jsxs("div", {
816
- className: "flex flex-row gap-2",
938
+ /*#__PURE__*/ jsx(FormHeader, {
939
+ method: method,
940
+ route: route,
941
+ isLoading: testQuery.isLoading
942
+ }),
943
+ /*#__PURE__*/ jsx(CollapsiblePanel, {
944
+ title: "Server URL",
945
+ children: /*#__PURE__*/ jsx(ServerSelect, {})
946
+ }),
947
+ header.length > 0 || authorization ? /*#__PURE__*/ jsxs(CollapsiblePanel, {
948
+ title: "Headers",
817
949
  children: [
818
- /*#__PURE__*/ jsx(RouteDisplay, {
819
- route: route
820
- }),
821
- /*#__PURE__*/ jsx("button", {
822
- type: "submit",
823
- className: cn(buttonVariants({
824
- color: 'secondary'
825
- })),
826
- disabled: testQuery.isLoading,
827
- children: "Send"
828
- })
950
+ authorization?.type === 'http' && authorization.scheme === 'basic' ? renderCustomField('authorization', {
951
+ name: 'Authorization',
952
+ type: 'object',
953
+ isRequired: true,
954
+ properties: {
955
+ username: {
956
+ type: 'string',
957
+ isRequired: true,
958
+ defaultValue: ''
959
+ },
960
+ password: {
961
+ type: 'string',
962
+ isRequired: true,
963
+ defaultValue: ''
964
+ }
965
+ }
966
+ }, fields.auth) : authorization ? renderCustomField('authorization', {
967
+ name: 'Authorization',
968
+ type: 'string',
969
+ isRequired: true,
970
+ description: 'The Authorization access token',
971
+ defaultValue: ''
972
+ }, fields.auth) : null,
973
+ header.map((field)=>renderCustomField(`header.${field.name}`, field, fields.header, field.name))
829
974
  ]
830
- }),
831
- authorization ? renderCustomField('authorization', authorization, fields.auth) : null,
975
+ }) : null,
832
976
  path.length > 0 ? /*#__PURE__*/ jsx(CollapsiblePanel, {
833
977
  title: "Path",
834
978
  children: path.map((field)=>renderCustomField(`path.${field.name}`, field, fields.path, field.name))
@@ -837,10 +981,6 @@ function APIPlayground({ route, method = 'GET', authorization, path = [], header
837
981
  title: "Query",
838
982
  children: query.map((field)=>renderCustomField(`query.${field.name}`, field, fields.query, field.name))
839
983
  }) : null,
840
- header.length > 0 ? /*#__PURE__*/ jsx(CollapsiblePanel, {
841
- title: "Headers",
842
- children: header.map((field)=>renderCustomField(`header.${field.name}`, field, fields.header, field.name))
843
- }) : null,
844
984
  body ? /*#__PURE__*/ jsx(CollapsiblePanel, {
845
985
  title: "Body",
846
986
  children: body.type === 'object' && !fields.body ? /*#__PURE__*/ jsx(ObjectInput, {
@@ -856,28 +996,6 @@ function APIPlayground({ route, method = 'GET', authorization, path = [], header
856
996
  })
857
997
  });
858
998
  }
859
- function CollapsiblePanel({ title, children }) {
860
- return /*#__PURE__*/ jsxs(Collapsible, {
861
- className: "-m-2",
862
- children: [
863
- /*#__PURE__*/ jsxs(CollapsibleTrigger, {
864
- className: "group flex w-full flex-row items-center justify-between p-2 font-medium",
865
- children: [
866
- title,
867
- /*#__PURE__*/ jsx(ChevronDown, {
868
- className: "size-4 group-data-[state=open]:rotate-180"
869
- })
870
- ]
871
- }),
872
- /*#__PURE__*/ jsx(CollapsibleContent, {
873
- children: /*#__PURE__*/ jsx("div", {
874
- className: "flex flex-col gap-4 p-2",
875
- children: children
876
- })
877
- })
878
- ]
879
- });
880
- }
881
999
  function createPathnameFromInput(route, path, query) {
882
1000
  let pathname = route;
883
1001
  for (const key of Object.keys(path)){
@@ -891,21 +1009,49 @@ function createPathnameFromInput(route, path, query) {
891
1009
  }
892
1010
  return searchParams.size > 0 ? `${pathname}?${searchParams.toString()}` : pathname;
893
1011
  }
894
- function RouteDisplay({ route }) {
895
- const [path, query] = useWatch({
896
- name: [
897
- 'path',
898
- 'query'
899
- ]
1012
+ function Route({ route, ...props }) {
1013
+ const segments = route.split('/').filter((part)=>part.length > 0);
1014
+ return /*#__PURE__*/ jsx("div", {
1015
+ ...props,
1016
+ className: cn('flex flex-row items-center gap-0.5 overflow-auto text-nowrap', props.className),
1017
+ children: segments.map((part, index)=>/*#__PURE__*/ jsxs(Fragment$1, {
1018
+ children: [
1019
+ /*#__PURE__*/ jsx("span", {
1020
+ className: "text-fd-muted-foreground",
1021
+ children: "/"
1022
+ }),
1023
+ part.startsWith('{') && part.endsWith('}') ? /*#__PURE__*/ jsx("code", {
1024
+ className: "bg-fd-primary/10 text-fd-primary",
1025
+ children: part
1026
+ }) : /*#__PURE__*/ jsx("code", {
1027
+ className: "text-fd-foreground",
1028
+ children: part
1029
+ })
1030
+ ]
1031
+ }, index))
900
1032
  });
901
- const pathname = useMemo(()=>createPathnameFromInput(route, path, query), [
902
- route,
903
- path,
904
- query
905
- ]);
906
- return /*#__PURE__*/ jsx("code", {
907
- className: "flex-1 overflow-auto text-nowrap rounded-lg border bg-fd-secondary px-2 py-1.5 text-sm text-fd-secondary-foreground",
908
- children: pathname
1033
+ }
1034
+ function FormHeader({ route, method, isLoading }) {
1035
+ return /*#__PURE__*/ jsxs("div", {
1036
+ className: "flex flex-row items-center gap-2 text-sm",
1037
+ children: [
1038
+ /*#__PURE__*/ jsx(MethodLabel, {
1039
+ children: method
1040
+ }),
1041
+ /*#__PURE__*/ jsx(Route, {
1042
+ route: route,
1043
+ className: "flex-1"
1044
+ }),
1045
+ /*#__PURE__*/ jsx("button", {
1046
+ type: "submit",
1047
+ className: cn(buttonVariants({
1048
+ color: 'primary',
1049
+ size: 'sm'
1050
+ }), 'px-3 py-1.5'),
1051
+ disabled: isLoading,
1052
+ children: "Send"
1053
+ })
1054
+ ]
909
1055
  });
910
1056
  }
911
1057
  function DefaultResultDisplay({ data }) {
@@ -937,32 +1083,34 @@ function DefaultResultDisplay({ data }) {
937
1083
  ]
938
1084
  });
939
1085
  }
940
- function useQuery(fn) {
941
- const [loading, setLoading] = useState(false);
942
- const [data, setData] = useState();
943
- return useMemo(()=>({
944
- isLoading: loading,
945
- data,
946
- start (input) {
947
- setLoading(true);
948
- void fn(input).then((res)=>{
949
- setData(res);
950
- }).catch(()=>{
951
- setData(undefined);
952
- }).finally(()=>{
953
- setLoading(false);
954
- });
955
- }
956
- }), [
957
- data,
958
- fn,
959
- loading
960
- ]);
1086
+ function CollapsiblePanel({ title, children, ...props }) {
1087
+ return /*#__PURE__*/ jsxs(Collapsible, {
1088
+ ...props,
1089
+ className: "border rounded-xl bg-fd-card text-fd-card-foreground overflow-hidden",
1090
+ children: [
1091
+ /*#__PURE__*/ jsxs(CollapsibleTrigger, {
1092
+ className: "group w-full inline-flex items-center gap-2 justify-between p-3 text-sm font-medium hover:bg-fd-accent",
1093
+ children: [
1094
+ title,
1095
+ /*#__PURE__*/ jsx(ChevronDown, {
1096
+ className: "size-4 group-data-[state=open]:rotate-180"
1097
+ })
1098
+ ]
1099
+ }),
1100
+ /*#__PURE__*/ jsx(CollapsibleContent, {
1101
+ children: /*#__PURE__*/ jsx("div", {
1102
+ className: "flex flex-col gap-4 p-3",
1103
+ children: children
1104
+ })
1105
+ })
1106
+ ]
1107
+ });
961
1108
  }
962
1109
 
963
1110
  var index = {
964
1111
  __proto__: null,
965
- APIPlayground: APIPlayground
1112
+ APIPlayground: APIPlayground,
1113
+ CollapsiblePanel: CollapsiblePanel
966
1114
  };
967
1115
 
968
- export { Input as I, Select as S, SelectTrigger as a, SelectValue as b, SelectContent as c, SelectItem as d, index as i, resolve as r };
1116
+ export { ChevronDown as C, Input as I, Select as S, SelectTrigger as a, SelectValue as b, SelectContent as c, SelectItem as d, index as i, labelVariants as l, resolve as r };