fumadocs-openapi 5.11.8 → 5.12.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,18 @@
1
1
  'use client';
2
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
3
3
  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';
4
+ import { forwardRef, useState, useMemo, useRef, useEffect, Fragment as Fragment$1 } from 'react';
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 { C as ChevronDown, a as ChevronUp, b as Check, 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-Die8irpf.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';
14
-
15
- const Form = FormProvider;
16
- const FormFieldContext = /*#__PURE__*/ createContext({
17
- name: ''
18
- });
19
- const FormItemContext = /*#__PURE__*/ createContext({
20
- id: ''
21
- });
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),
54
- ...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';
11
+ import { S as ServerSelect } from './server-select-client-D4GEjFgD.js';
12
+ import { Collapsible, CollapsibleTrigger, CollapsibleContent } from 'fumadocs-ui/components/ui/collapsible';
13
+ import { buttonVariants as buttonVariants$1 } from 'fumadocs-ui/components/ui/button';
14
+ import { ApiClientModalProvider, useApiClientModal } from '@scalar/api-client-react';
15
+ import { useTheme } from 'next-themes';
91
16
 
92
17
  /**
93
18
  * Resolve reference
@@ -127,7 +52,7 @@ const Select = SelectPrimitive.Root;
127
52
  const SelectValue = SelectPrimitive.Value;
128
53
  const SelectTrigger = /*#__PURE__*/ forwardRef(({ className, children, ...props }, ref)=>/*#__PURE__*/ jsxs(SelectPrimitive.Trigger, {
129
54
  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),
55
+ 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
56
  ...props,
132
57
  children: [
133
58
  children,
@@ -158,16 +83,16 @@ const SelectScrollDownButton = /*#__PURE__*/ forwardRef(({ className, ...props }
158
83
  })
159
84
  }));
160
85
  SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
161
- const SelectContent = /*#__PURE__*/ forwardRef(({ className, children, position = 'popper', ...props }, ref)=>/*#__PURE__*/ jsx(SelectPrimitive.Portal, {
86
+ const SelectContent = /*#__PURE__*/ forwardRef(({ className, children, position, ...props }, ref)=>/*#__PURE__*/ jsx(SelectPrimitive.Portal, {
162
87
  children: /*#__PURE__*/ jsxs(SelectPrimitive.Content, {
163
88
  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),
89
+ className: cn('z-50 overflow-hidden rounded-lg border bg-fd-popover text-fd-popover-foreground shadow-md', className),
165
90
  position: position,
166
91
  ...props,
167
92
  children: [
168
93
  /*#__PURE__*/ jsx(SelectScrollUpButton, {}),
169
94
  /*#__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)]'),
95
+ className: "p-1",
171
96
  children: children
172
97
  }),
173
98
  /*#__PURE__*/ jsx(SelectScrollDownButton, {})
@@ -183,7 +108,7 @@ const SelectLabel = /*#__PURE__*/ forwardRef(({ className, ...props }, ref)=>/*#
183
108
  SelectLabel.displayName = SelectPrimitive.Label.displayName;
184
109
  const SelectItem = /*#__PURE__*/ forwardRef(({ className, children, ...props }, ref)=>/*#__PURE__*/ jsxs(SelectPrimitive.Item, {
185
110
  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),
111
+ 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
112
  ...props,
188
113
  children: [
189
114
  /*#__PURE__*/ jsx(SelectPrimitive.ItemIndicator, {
@@ -205,64 +130,36 @@ const SelectSeparator = /*#__PURE__*/ forwardRef(({ className, ...props }, ref)=
205
130
  }));
206
131
  SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
207
132
 
133
+ const labelVariants = cva('text-[13px] font-mono text-fd-card-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-70');
208
134
  const Input = /*#__PURE__*/ React.forwardRef(({ className, type, ...props }, ref)=>{
209
135
  return /*#__PURE__*/ jsx("input", {
210
136
  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),
137
+ 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
138
  ref: ref,
213
139
  ...props
214
140
  });
215
141
  });
216
142
  Input.displayName = 'Input';
217
143
 
218
- function renderInner({ field, ...props }) {
219
- if (field.type === 'object') return /*#__PURE__*/ jsx(ObjectInput, {
220
- field: field,
221
- ...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", {
144
+ function FieldHeader({ name, required = false, type, ...props }) {
145
+ return /*#__PURE__*/ jsxs("label", {
242
146
  ...props,
243
- className: cn('flex flex-col gap-1', props.className),
147
+ className: cn('w-full inline-flex items-center gap-1', props.className),
244
148
  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
- ]
149
+ /*#__PURE__*/ jsx("span", {
150
+ className: cn(labelVariants()),
151
+ children: name
262
152
  }),
263
- !inline ? /*#__PURE__*/ jsx("p", {
264
- className: "text-xs",
265
- children: description
153
+ required ? /*#__PURE__*/ jsx("span", {
154
+ className: "text-red-500",
155
+ children: "*"
156
+ }) : null,
157
+ /*#__PURE__*/ jsx("div", {
158
+ className: "flex-1"
159
+ }),
160
+ type ? /*#__PURE__*/ jsx("code", {
161
+ className: "text-xs text-fd-muted-foreground",
162
+ children: type
266
163
  }) : null,
267
164
  props.children
268
165
  ]
@@ -272,9 +169,9 @@ function ObjectInput({ field, fieldName, ...props }) {
272
169
  const { references } = useSchemaContext();
273
170
  return /*#__PURE__*/ jsxs("div", {
274
171
  ...props,
275
- className: cn('flex flex-col gap-4', props.className),
172
+ className: cn('flex flex-col gap-6', props.className),
276
173
  children: [
277
- Object.entries(field.properties).map(([key, child])=>/*#__PURE__*/ jsx(InputField, {
174
+ Object.entries(field.properties).map(([key, child])=>/*#__PURE__*/ jsx(FieldSet, {
278
175
  name: key,
279
176
  field: resolve(child, references),
280
177
  fieldName: `${fieldName}.${key}`
@@ -295,13 +192,11 @@ function AdditionalProperties({ fieldName, type }) {
295
192
  if (d?.type === 'object') return d.properties;
296
193
  return [];
297
194
  });
298
- useOnChange(properties, ()=>{
299
- dynamic.current.set(`additional_${fieldName}`, {
300
- type: 'object',
301
- properties
302
- });
195
+ dynamic.current.set(`additional_${fieldName}`, {
196
+ type: 'object',
197
+ properties
303
198
  });
304
- const onAppend = useCallback(()=>{
199
+ const onAppend = ()=>{
305
200
  const name = nextName.trim();
306
201
  if (name.length === 0) return;
307
202
  setProperties((p)=>{
@@ -313,15 +208,11 @@ function AdditionalProperties({ fieldName, type }) {
313
208
  name
314
209
  ];
315
210
  });
316
- }, [
317
- nextName,
318
- setValue,
319
- fieldName
320
- ]);
211
+ };
321
212
  const types = typeof type === 'string' ? resolveDynamicTypes(references[type], references) : undefined;
322
213
  return /*#__PURE__*/ jsxs(Fragment, {
323
214
  children: [
324
- properties.map((item)=>/*#__PURE__*/ jsx(Switcher, {
215
+ properties.map((item)=>/*#__PURE__*/ jsx(FieldSet, {
325
216
  name: item,
326
217
  field: {
327
218
  type: 'switcher',
@@ -351,17 +242,15 @@ function AdditionalProperties({ fieldName, type }) {
351
242
  /*#__PURE__*/ jsx(Input, {
352
243
  value: nextName,
353
244
  placeholder: "Enter Property Name",
354
- onChange: useCallback((e)=>{
245
+ onChange: (e)=>{
355
246
  setNextName(e.target.value);
356
- }, []),
357
- onKeyDown: useCallback((e)=>{
247
+ },
248
+ onKeyDown: (e)=>{
358
249
  if (e.key === 'Enter') {
359
250
  onAppend();
360
251
  e.preventDefault();
361
252
  }
362
- }, [
363
- onAppend
364
- ])
253
+ }
365
254
  }),
366
255
  /*#__PURE__*/ jsx("button", {
367
256
  type: "button",
@@ -417,11 +306,84 @@ anyFields.array = {
417
306
  items: anyFields
418
307
  }
419
308
  };
420
- function Switcher({ field, fieldName, ...props }) {
309
+ function FieldInput({ field, fieldName, ...props }) {
310
+ const { control, register } = useFormContext();
311
+ if (field.type === 'null') return null;
312
+ if (field.type === 'object') {
313
+ return /*#__PURE__*/ jsx(ObjectInput, {
314
+ field: field,
315
+ fieldName: fieldName,
316
+ ...props,
317
+ className: cn('rounded-lg border border-fd-primary/20 bg-fd-card p-3 shadow-sm', props.className)
318
+ });
319
+ }
320
+ if (field.type === 'array') {
321
+ return /*#__PURE__*/ jsx(ArrayInput, {
322
+ fieldName: fieldName,
323
+ field: field,
324
+ ...props,
325
+ className: cn('rounded-lg border border-fd-primary/20 bg-fd-background p-3 shadow-sm', props.className)
326
+ });
327
+ }
328
+ if (field.type === 'file' || field.type === 'boolean') {
329
+ return /*#__PURE__*/ jsx(Controller, {
330
+ control: control,
331
+ name: fieldName,
332
+ render: ({ field: { value, onChange, ...restField } })=>field.type === 'file' ? /*#__PURE__*/ jsx("input", {
333
+ id: fieldName,
334
+ type: "file",
335
+ multiple: false,
336
+ onChange: (e)=>{
337
+ if (!e.target.files) return;
338
+ onChange(e.target.files.item(0));
339
+ },
340
+ ...props,
341
+ ...restField
342
+ }) : /*#__PURE__*/ jsxs(Select, {
343
+ value: value,
344
+ onValueChange: onChange,
345
+ disabled: restField.disabled,
346
+ children: [
347
+ /*#__PURE__*/ jsx(SelectTrigger, {
348
+ id: fieldName,
349
+ className: props.className,
350
+ ...restField,
351
+ children: /*#__PURE__*/ jsx(SelectValue, {})
352
+ }),
353
+ /*#__PURE__*/ jsxs(SelectContent, {
354
+ children: [
355
+ /*#__PURE__*/ jsx(SelectItem, {
356
+ value: "true",
357
+ children: "True"
358
+ }),
359
+ /*#__PURE__*/ jsx(SelectItem, {
360
+ value: "false",
361
+ children: "False"
362
+ }),
363
+ field.isRequired ? null : /*#__PURE__*/ jsx(SelectItem, {
364
+ value: "null",
365
+ children: "Null"
366
+ })
367
+ ]
368
+ })
369
+ ]
370
+ })
371
+ });
372
+ }
373
+ return /*#__PURE__*/ jsx(Input, {
374
+ id: fieldName,
375
+ placeholder: "Enter value",
376
+ type: field.type === 'string' ? 'text' : 'number',
377
+ ...register(fieldName),
378
+ ...props
379
+ });
380
+ }
381
+ function FieldSet({ field, fieldName, toolbar, name, ...props }) {
421
382
  const { references, dynamic } = useSchemaContext();
422
- const items = Object.keys(field.items);
423
383
  const [value, setValue] = useState(()=>{
384
+ if (field.type !== 'switcher') return '';
424
385
  const d = dynamic.current.get(fieldName);
386
+ const items = Object.keys(field.items);
425
387
  if (d?.type === 'field') {
426
388
  // schemas are passed from server components, they shouldn't be re-constructed
427
389
  const cached = items.find((item)=>d.schema === field.items[item]);
@@ -429,193 +391,66 @@ function Switcher({ field, fieldName, ...props }) {
429
391
  }
430
392
  return items[0];
431
393
  });
432
- useOnChange(value, ()=>{
433
- if (!value) return;
394
+ if (field.type === 'null') return null;
395
+ if (value && field.type === 'switcher') {
434
396
  dynamic.current.set(fieldName, {
435
397
  type: 'field',
436
398
  schema: field.items[value]
437
399
  });
438
- });
439
- return /*#__PURE__*/ jsx(InputContainer, {
440
- required: field.isRequired,
441
- description: field.description,
442
- ...props,
443
- toolbar: /*#__PURE__*/ jsxs(Fragment, {
400
+ }
401
+ if (field.type === 'switcher') {
402
+ const child = resolve(field.items[value], references);
403
+ return /*#__PURE__*/ jsxs("fieldset", {
404
+ ...props,
405
+ className: cn('flex flex-col gap-1.5', props.className),
444
406
  children: [
445
- /*#__PURE__*/ jsxs(Select, {
446
- value: value,
447
- onValueChange: setValue,
407
+ /*#__PURE__*/ jsxs(FieldHeader, {
408
+ name: name,
409
+ htmlFor: fieldName,
410
+ required: field.isRequired,
448
411
  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, {
412
+ /*#__PURE__*/ jsx("select", {
413
+ value: value,
414
+ onChange: (e)=>setValue(e.target.value),
415
+ className: "text-xs",
416
+ children: Object.keys(field.items).map((item)=>/*#__PURE__*/ jsx("option", {
455
417
  value: item,
456
418
  children: item
457
419
  }, 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
420
  }),
524
421
  toolbar
525
422
  ]
526
423
  }),
527
- !inline ? /*#__PURE__*/ jsx(FormDescription, {
528
- className: "text-xs",
424
+ /*#__PURE__*/ jsx("p", {
425
+ className: "text-xs text-fd-muted-foreground",
529
426
  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
- ]
427
+ }),
428
+ child.type === 'switcher' ? /*#__PURE__*/ jsx(FieldSet, {
429
+ field: child,
430
+ fieldName: fieldName
431
+ }) : /*#__PURE__*/ jsx(FieldInput, {
432
+ field: child,
433
+ fieldName: fieldName
599
434
  })
435
+ ]
600
436
  });
601
437
  }
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
- ]
438
+ return /*#__PURE__*/ jsxs("fieldset", {
439
+ ...props,
440
+ className: cn('flex flex-col gap-1.5', props.className),
441
+ children: [
442
+ /*#__PURE__*/ jsx(FieldHeader, {
443
+ htmlFor: fieldName,
444
+ name: name,
445
+ required: field.isRequired,
446
+ type: field.type,
447
+ children: toolbar
448
+ }),
449
+ /*#__PURE__*/ jsx(FieldInput, {
450
+ field: field,
451
+ fieldName: fieldName
618
452
  })
453
+ ]
619
454
  });
620
455
  }
621
456
  function ArrayInput({ fieldName, field, ...props }) {
@@ -624,23 +459,14 @@ function ArrayInput({ fieldName, field, ...props }) {
624
459
  const { fields, append, remove } = useFieldArray({
625
460
  name: fieldName
626
461
  });
627
- const handleAppend = useCallback(()=>{
628
- append(getDefaultValue(items, references));
629
- }, [
630
- append,
631
- references,
632
- items
633
- ]);
634
462
  return /*#__PURE__*/ jsxs("div", {
635
463
  ...props,
636
- className: cn('flex flex-col gap-4', props.className),
464
+ className: cn('flex flex-col gap-2', props.className),
637
465
  children: [
638
- fields.map((item, index)=>/*#__PURE__*/ jsx(InputField, {
639
- inline: true,
640
- name: `Item ${String(index + 1)}`,
466
+ fields.map((item, index)=>/*#__PURE__*/ jsx(FieldSet, {
467
+ name: `${fieldName.split('.').at(-1)}[${index}]`,
641
468
  field: items,
642
- fieldName: `${fieldName}.${String(index)}`,
643
- className: "flex-1",
469
+ fieldName: `${fieldName}.${index}`,
644
470
  toolbar: /*#__PURE__*/ jsx("button", {
645
471
  type: "button",
646
472
  "aria-label": "Remove Item",
@@ -659,10 +485,13 @@ function ArrayInput({ fieldName, field, ...props }) {
659
485
  /*#__PURE__*/ jsxs("button", {
660
486
  type: "button",
661
487
  className: cn(buttonVariants({
662
- color: 'secondary',
663
- className: 'gap-1.5'
488
+ color: 'outline',
489
+ className: 'gap-1.5 py-2',
490
+ size: 'sm'
664
491
  })),
665
- onClick: handleAppend,
492
+ onClick: ()=>{
493
+ append(getDefaultValue(items, references));
494
+ },
666
495
  children: [
667
496
  /*#__PURE__*/ jsx(Plus, {
668
497
  className: "size-4"
@@ -726,6 +555,64 @@ function getStatusInfo(status) {
726
555
  };
727
556
  }
728
557
 
558
+ const variants = cva('font-mono font-medium', {
559
+ variants: {
560
+ color: {
561
+ green: 'text-green-600 dark:text-green-400',
562
+ yellow: 'text-yellow-600 dark:text-yellow-400',
563
+ red: 'text-red-600 dark:text-red-400',
564
+ blue: 'text-blue-600 dark:text-blue-400',
565
+ orange: 'text-orange-600 dark:text-orange-400'
566
+ }
567
+ }
568
+ });
569
+ function getBadgeColor(method) {
570
+ switch(method.toUpperCase()){
571
+ case 'PUT':
572
+ return 'yellow';
573
+ case 'PATCH':
574
+ return 'orange';
575
+ case 'POST':
576
+ return 'blue';
577
+ case 'DELETE':
578
+ return 'red';
579
+ default:
580
+ return 'green';
581
+ }
582
+ }
583
+ function MethodLabel({ children, ...props }) {
584
+ return /*#__PURE__*/ jsx("span", {
585
+ ...props,
586
+ className: cn(variants({
587
+ color: getBadgeColor(children)
588
+ }), props.className),
589
+ children: children.toUpperCase()
590
+ });
591
+ }
592
+
593
+ function useQuery(fn) {
594
+ const [loading, setLoading] = useState(false);
595
+ const [data, setData] = useState();
596
+ return useMemo(()=>({
597
+ isLoading: loading,
598
+ data,
599
+ start (input) {
600
+ setLoading(true);
601
+ void fn(input).then((res)=>{
602
+ setData(res);
603
+ }).catch(()=>{
604
+ setData(undefined);
605
+ }).finally(()=>{
606
+ setLoading(false);
607
+ });
608
+ }
609
+ }), [
610
+ data,
611
+ fn,
612
+ loading
613
+ ]);
614
+ }
615
+
729
616
  function APIPlayground({ route, method = 'GET', authorization, path = [], header = [], query = [], body, fields = {}, schemas, proxyUrl, components: { ResultDisplay = DefaultResultDisplay } = {}, ...props }) {
730
617
  const { serverRef } = useApiContext();
731
618
  const dynamicRef = useRef(new Map());
@@ -739,7 +626,7 @@ function APIPlayground({ route, method = 'GET', authorization, path = [], header
739
626
  }
740
627
  });
741
628
  const testQuery = useQuery(async (input)=>{
742
- const fetcher = await import('./fetcher-Cc3BieIx.js').then((mod)=>mod.createBrowserFetcher(body, schemas));
629
+ const fetcher = await import('./fetcher-BHk80ZFu.js').then((mod)=>mod.createBrowserFetcher(body, schemas));
743
630
  const serverUrl = serverRef.current ? getUrl(serverRef.current.url, serverRef.current.variables) : window.location.origin;
744
631
  let url = `${serverUrl}${createPathnameFromInput(route, input.path, input.query)}`;
745
632
  if (proxyUrl) {
@@ -792,13 +679,13 @@ function APIPlayground({ route, method = 'GET', authorization, path = [], header
792
679
  name: fieldName
793
680
  }, key);
794
681
  }
795
- return /*#__PURE__*/ jsx(InputField, {
682
+ return /*#__PURE__*/ jsx(FieldSet, {
796
683
  name: info.name,
797
684
  fieldName: fieldName,
798
685
  field: info
799
686
  }, key);
800
687
  }
801
- return /*#__PURE__*/ jsx(Form, {
688
+ return /*#__PURE__*/ jsx(FormProvider, {
802
689
  ...form,
803
690
  children: /*#__PURE__*/ jsx(SchemaContext.Provider, {
804
691
  value: useMemo(()=>({
@@ -809,26 +696,22 @@ function APIPlayground({ route, method = 'GET', authorization, path = [], header
809
696
  ]),
810
697
  children: /*#__PURE__*/ jsxs("form", {
811
698
  ...props,
812
- className: cn('not-prose flex flex-col gap-5 rounded-xl border bg-fd-card p-3', props.className),
699
+ className: cn('not-prose flex flex-col gap-2 rounded-xl border p-3 shadow-md', props.className),
813
700
  onSubmit: onSubmit,
814
701
  children: [
815
- /*#__PURE__*/ jsxs("div", {
816
- className: "flex flex-row gap-2",
817
- 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
- })
829
- ]
702
+ /*#__PURE__*/ jsx(FormHeader, {
703
+ method: method,
704
+ route: route,
705
+ isLoading: testQuery.isLoading
706
+ }),
707
+ /*#__PURE__*/ jsx(CollapsiblePanel, {
708
+ title: "Server URL",
709
+ children: /*#__PURE__*/ jsx(ServerSelect, {})
830
710
  }),
831
- authorization ? renderCustomField('authorization', authorization, fields.auth) : null,
711
+ authorization ? /*#__PURE__*/ jsx(CollapsiblePanel, {
712
+ title: "Headers",
713
+ children: renderCustomField('authorization', authorization, fields.auth)
714
+ }) : null,
832
715
  path.length > 0 ? /*#__PURE__*/ jsx(CollapsiblePanel, {
833
716
  title: "Path",
834
717
  children: path.map((field)=>renderCustomField(`path.${field.name}`, field, fields.path, field.name))
@@ -856,28 +739,6 @@ function APIPlayground({ route, method = 'GET', authorization, path = [], header
856
739
  })
857
740
  });
858
741
  }
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
742
  function createPathnameFromInput(route, path, query) {
882
743
  let pathname = route;
883
744
  for (const key of Object.keys(path)){
@@ -891,21 +752,49 @@ function createPathnameFromInput(route, path, query) {
891
752
  }
892
753
  return searchParams.size > 0 ? `${pathname}?${searchParams.toString()}` : pathname;
893
754
  }
894
- function RouteDisplay({ route }) {
895
- const [path, query] = useWatch({
896
- name: [
897
- 'path',
898
- 'query'
899
- ]
755
+ function Route({ route, ...props }) {
756
+ const segments = route.split('/').filter((part)=>part.length > 0);
757
+ return /*#__PURE__*/ jsx("div", {
758
+ ...props,
759
+ className: cn('flex flex-row items-center gap-0.5 overflow-auto text-nowrap', props.className),
760
+ children: segments.map((part, index)=>/*#__PURE__*/ jsxs(Fragment$1, {
761
+ children: [
762
+ /*#__PURE__*/ jsx("span", {
763
+ className: "text-fd-muted-foreground",
764
+ children: "/"
765
+ }),
766
+ part.startsWith('{') && part.endsWith('}') ? /*#__PURE__*/ jsx("code", {
767
+ className: "bg-fd-primary/10 text-fd-primary",
768
+ children: part
769
+ }) : /*#__PURE__*/ jsx("code", {
770
+ className: "text-fd-foreground",
771
+ children: part
772
+ })
773
+ ]
774
+ }, index))
900
775
  });
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
776
+ }
777
+ function FormHeader({ route, method, isLoading }) {
778
+ return /*#__PURE__*/ jsxs("div", {
779
+ className: "flex flex-row items-center gap-2 text-sm",
780
+ children: [
781
+ /*#__PURE__*/ jsx(MethodLabel, {
782
+ children: method
783
+ }),
784
+ /*#__PURE__*/ jsx(Route, {
785
+ route: route,
786
+ className: "flex-1"
787
+ }),
788
+ /*#__PURE__*/ jsx("button", {
789
+ type: "submit",
790
+ className: cn(buttonVariants({
791
+ color: 'primary',
792
+ size: 'sm'
793
+ }), 'px-3 py-1.5'),
794
+ disabled: isLoading,
795
+ children: "Send"
796
+ })
797
+ ]
909
798
  });
910
799
  }
911
800
  function DefaultResultDisplay({ data }) {
@@ -937,32 +826,87 @@ function DefaultResultDisplay({ data }) {
937
826
  ]
938
827
  });
939
828
  }
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
- ]);
829
+ function CollapsiblePanel({ title, children, ...props }) {
830
+ return /*#__PURE__*/ jsxs(Collapsible, {
831
+ ...props,
832
+ className: "border rounded-xl bg-fd-card text-fd-card-foreground overflow-hidden",
833
+ children: [
834
+ /*#__PURE__*/ jsxs(CollapsibleTrigger, {
835
+ className: "group w-full inline-flex items-center gap-2 justify-between p-3 text-sm font-medium hover:bg-fd-accent",
836
+ children: [
837
+ title,
838
+ /*#__PURE__*/ jsx(ChevronDown, {
839
+ className: "size-4 group-data-[state=open]:rotate-180"
840
+ })
841
+ ]
842
+ }),
843
+ /*#__PURE__*/ jsx(CollapsibleContent, {
844
+ children: /*#__PURE__*/ jsx("div", {
845
+ className: "flex flex-col gap-4 p-3",
846
+ children: children
847
+ })
848
+ })
849
+ ]
850
+ });
851
+ }
852
+
853
+ var index$1 = {
854
+ __proto__: null,
855
+ APIPlayground: APIPlayground,
856
+ CollapsiblePanel: CollapsiblePanel
857
+ };
858
+
859
+ function ScalarPlayground({ path, method, spec }) {
860
+ const { resolvedTheme } = useTheme();
861
+ const [mounted, setMounted] = useState(false);
862
+ useEffect(()=>{
863
+ setMounted(true);
864
+ }, []);
865
+ return /*#__PURE__*/ jsxs("div", {
866
+ className: cn('flex flex-row items-center gap-2.5 p-3 rounded-xl border bg-fd-card text-fd-card-foreground not-prose', mounted ? `${resolvedTheme}-mode` : null),
867
+ children: [
868
+ /*#__PURE__*/ jsx(MethodLabel, {
869
+ className: "text-xs",
870
+ children: method
871
+ }),
872
+ /*#__PURE__*/ jsx("code", {
873
+ className: "flex-1 overflow-auto text-nowrap text-[13px] text-fd-muted-foreground",
874
+ children: path
875
+ }),
876
+ /*#__PURE__*/ jsx(ApiClientModalProvider, {
877
+ configuration: {
878
+ themeId: 'moon',
879
+ spec: {
880
+ content: spec
881
+ }
882
+ },
883
+ children: /*#__PURE__*/ jsx(Trigger, {
884
+ path: path,
885
+ method: method
886
+ })
887
+ })
888
+ ]
889
+ });
890
+ }
891
+ function Trigger({ path, method }) {
892
+ const client = useApiClientModal();
893
+ return /*#__PURE__*/ jsx("button", {
894
+ type: "submit",
895
+ className: cn(buttonVariants$1({
896
+ color: 'primary',
897
+ size: 'sm'
898
+ }), 'px-3 py-1.5'),
899
+ onClick: ()=>client?.open({
900
+ path,
901
+ method
902
+ }),
903
+ children: "Test"
904
+ });
961
905
  }
962
906
 
963
907
  var index = {
964
908
  __proto__: null,
965
- APIPlayground: APIPlayground
909
+ default: ScalarPlayground
966
910
  };
967
911
 
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 };
912
+ export { Input as I, Select as S, SelectTrigger as a, SelectValue as b, SelectContent as c, SelectItem as d, index as e, index$1 as i, labelVariants as l, resolve as r };