@djangocfg/ui-nextjs 2.1.89 → 2.1.91

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.
Files changed (161) hide show
  1. package/README.md +6 -15
  2. package/package.json +6 -25
  3. package/src/blocks/SplitHero/SplitHeroMedia.tsx +1 -1
  4. package/src/components/index.ts +0 -40
  5. package/src/hooks/index.ts +0 -6
  6. package/src/index.ts +2 -11
  7. package/src/components/button-download.tsx +0 -277
  8. package/src/components/markdown/MarkdownMessage.tsx +0 -340
  9. package/src/components/markdown/index.ts +0 -5
  10. package/src/components/menubar.tsx +0 -275
  11. package/src/components/multi-select-pro/async.tsx +0 -598
  12. package/src/components/multi-select-pro/helpers.tsx +0 -84
  13. package/src/components/multi-select-pro/index.tsx +0 -612
  14. package/src/components/navigation-menu.tsx +0 -154
  15. package/src/components/otp/index.tsx +0 -197
  16. package/src/components/otp/types.ts +0 -133
  17. package/src/components/otp/use-otp-input.ts +0 -225
  18. package/src/components/phone-input.tsx +0 -277
  19. package/src/components/sonner.tsx +0 -32
  20. package/src/hooks/useLocalStorage.ts +0 -300
  21. package/src/hooks/useSessionStorage.ts +0 -290
  22. package/src/lib/index.ts +0 -5
  23. package/src/lib/logger/index.ts +0 -10
  24. package/src/lib/logger/logStore.ts +0 -122
  25. package/src/lib/logger/logger.ts +0 -175
  26. package/src/lib/logger/types.ts +0 -82
  27. package/src/stores/index.ts +0 -8
  28. package/src/stores/mediaCache.ts +0 -534
  29. package/src/tools/AudioPlayer/README.md +0 -206
  30. package/src/tools/AudioPlayer/components/HybridAudioPlayer.tsx +0 -216
  31. package/src/tools/AudioPlayer/components/HybridSimplePlayer.tsx +0 -280
  32. package/src/tools/AudioPlayer/components/HybridWaveform.tsx +0 -279
  33. package/src/tools/AudioPlayer/components/ReactiveCover/AudioReactiveCover.tsx +0 -149
  34. package/src/tools/AudioPlayer/components/ReactiveCover/effects/GlowEffect.tsx +0 -110
  35. package/src/tools/AudioPlayer/components/ReactiveCover/effects/MeshEffect.tsx +0 -58
  36. package/src/tools/AudioPlayer/components/ReactiveCover/effects/OrbsEffect.tsx +0 -45
  37. package/src/tools/AudioPlayer/components/ReactiveCover/effects/SpotlightEffect.tsx +0 -82
  38. package/src/tools/AudioPlayer/components/ReactiveCover/effects/index.ts +0 -8
  39. package/src/tools/AudioPlayer/components/ReactiveCover/index.ts +0 -6
  40. package/src/tools/AudioPlayer/components/index.ts +0 -22
  41. package/src/tools/AudioPlayer/context/HybridAudioProvider.tsx +0 -158
  42. package/src/tools/AudioPlayer/context/index.ts +0 -16
  43. package/src/tools/AudioPlayer/effects/index.ts +0 -412
  44. package/src/tools/AudioPlayer/hooks/index.ts +0 -35
  45. package/src/tools/AudioPlayer/hooks/useHybridAudio.ts +0 -387
  46. package/src/tools/AudioPlayer/hooks/useHybridAudioAnalysis.ts +0 -95
  47. package/src/tools/AudioPlayer/hooks/useVisualization.tsx +0 -207
  48. package/src/tools/AudioPlayer/index.ts +0 -133
  49. package/src/tools/AudioPlayer/types/effects.ts +0 -73
  50. package/src/tools/AudioPlayer/types/index.ts +0 -27
  51. package/src/tools/AudioPlayer/utils/debug.ts +0 -14
  52. package/src/tools/AudioPlayer/utils/formatTime.ts +0 -10
  53. package/src/tools/AudioPlayer/utils/index.ts +0 -6
  54. package/src/tools/ImageViewer/@refactoring/00-PLAN.md +0 -71
  55. package/src/tools/ImageViewer/@refactoring/01-TYPES.md +0 -121
  56. package/src/tools/ImageViewer/@refactoring/02-UTILS.md +0 -143
  57. package/src/tools/ImageViewer/@refactoring/03-HOOKS.md +0 -261
  58. package/src/tools/ImageViewer/@refactoring/04-COMPONENTS.md +0 -427
  59. package/src/tools/ImageViewer/@refactoring/05-EXECUTION-CHECKLIST.md +0 -126
  60. package/src/tools/ImageViewer/README.md +0 -200
  61. package/src/tools/ImageViewer/components/ImageInfo.tsx +0 -44
  62. package/src/tools/ImageViewer/components/ImageToolbar.tsx +0 -150
  63. package/src/tools/ImageViewer/components/ImageViewer.tsx +0 -241
  64. package/src/tools/ImageViewer/components/index.ts +0 -7
  65. package/src/tools/ImageViewer/hooks/index.ts +0 -9
  66. package/src/tools/ImageViewer/hooks/useImageLoading.ts +0 -204
  67. package/src/tools/ImageViewer/hooks/useImageTransform.ts +0 -101
  68. package/src/tools/ImageViewer/index.ts +0 -60
  69. package/src/tools/ImageViewer/types.ts +0 -81
  70. package/src/tools/ImageViewer/utils/constants.ts +0 -59
  71. package/src/tools/ImageViewer/utils/debug.ts +0 -14
  72. package/src/tools/ImageViewer/utils/index.ts +0 -17
  73. package/src/tools/ImageViewer/utils/lqip.ts +0 -47
  74. package/src/tools/JsonForm/JsonSchemaForm.tsx +0 -197
  75. package/src/tools/JsonForm/examples/BotConfigExample.tsx +0 -249
  76. package/src/tools/JsonForm/examples/RealBotConfigExample.tsx +0 -161
  77. package/src/tools/JsonForm/index.ts +0 -46
  78. package/src/tools/JsonForm/templates/ArrayFieldItemTemplate.tsx +0 -47
  79. package/src/tools/JsonForm/templates/ArrayFieldTemplate.tsx +0 -74
  80. package/src/tools/JsonForm/templates/BaseInputTemplate.tsx +0 -107
  81. package/src/tools/JsonForm/templates/ErrorListTemplate.tsx +0 -35
  82. package/src/tools/JsonForm/templates/FieldTemplate.tsx +0 -62
  83. package/src/tools/JsonForm/templates/ObjectFieldTemplate.tsx +0 -116
  84. package/src/tools/JsonForm/templates/index.ts +0 -12
  85. package/src/tools/JsonForm/types.ts +0 -83
  86. package/src/tools/JsonForm/utils.ts +0 -213
  87. package/src/tools/JsonForm/widgets/CheckboxWidget.tsx +0 -37
  88. package/src/tools/JsonForm/widgets/ColorWidget.tsx +0 -219
  89. package/src/tools/JsonForm/widgets/NumberWidget.tsx +0 -89
  90. package/src/tools/JsonForm/widgets/SelectWidget.tsx +0 -97
  91. package/src/tools/JsonForm/widgets/SliderWidget.tsx +0 -148
  92. package/src/tools/JsonForm/widgets/SwitchWidget.tsx +0 -35
  93. package/src/tools/JsonForm/widgets/TextWidget.tsx +0 -96
  94. package/src/tools/JsonForm/widgets/index.ts +0 -14
  95. package/src/tools/JsonTree/index.tsx +0 -243
  96. package/src/tools/LottiePlayer/LottiePlayer.client.tsx +0 -213
  97. package/src/tools/LottiePlayer/index.tsx +0 -55
  98. package/src/tools/LottiePlayer/types.ts +0 -108
  99. package/src/tools/LottiePlayer/useLottie.ts +0 -164
  100. package/src/tools/Mermaid/Mermaid.client.tsx +0 -82
  101. package/src/tools/Mermaid/components/MermaidCodeViewer.tsx +0 -95
  102. package/src/tools/Mermaid/components/MermaidFullscreenModal.tsx +0 -103
  103. package/src/tools/Mermaid/hooks/index.ts +0 -4
  104. package/src/tools/Mermaid/hooks/useMermaidCleanup.ts +0 -73
  105. package/src/tools/Mermaid/hooks/useMermaidFullscreen.ts +0 -46
  106. package/src/tools/Mermaid/hooks/useMermaidRenderer.ts +0 -226
  107. package/src/tools/Mermaid/hooks/useMermaidValidation.ts +0 -29
  108. package/src/tools/Mermaid/index.tsx +0 -41
  109. package/src/tools/Mermaid/utils/mermaid-helpers.ts +0 -33
  110. package/src/tools/OpenapiViewer/components/EndpointInfo.tsx +0 -149
  111. package/src/tools/OpenapiViewer/components/EndpointsLibrary.tsx +0 -263
  112. package/src/tools/OpenapiViewer/components/PlaygroundLayout.tsx +0 -125
  113. package/src/tools/OpenapiViewer/components/PlaygroundStepper.tsx +0 -100
  114. package/src/tools/OpenapiViewer/components/RequestBuilder.tsx +0 -157
  115. package/src/tools/OpenapiViewer/components/RequestParametersForm.tsx +0 -253
  116. package/src/tools/OpenapiViewer/components/ResponseViewer.tsx +0 -173
  117. package/src/tools/OpenapiViewer/components/VersionSelector.tsx +0 -68
  118. package/src/tools/OpenapiViewer/components/index.ts +0 -14
  119. package/src/tools/OpenapiViewer/constants.ts +0 -39
  120. package/src/tools/OpenapiViewer/context/PlaygroundContext.tsx +0 -337
  121. package/src/tools/OpenapiViewer/hooks/index.ts +0 -8
  122. package/src/tools/OpenapiViewer/hooks/useMobile.ts +0 -10
  123. package/src/tools/OpenapiViewer/hooks/useOpenApiSchema.ts +0 -199
  124. package/src/tools/OpenapiViewer/index.tsx +0 -38
  125. package/src/tools/OpenapiViewer/types.ts +0 -151
  126. package/src/tools/OpenapiViewer/utils/apiKeyManager.ts +0 -149
  127. package/src/tools/OpenapiViewer/utils/formatters.ts +0 -71
  128. package/src/tools/OpenapiViewer/utils/index.ts +0 -9
  129. package/src/tools/OpenapiViewer/utils/versionManager.ts +0 -161
  130. package/src/tools/PrettyCode/PrettyCode.client.tsx +0 -208
  131. package/src/tools/PrettyCode/index.tsx +0 -45
  132. package/src/tools/VideoPlayer/@refactoring/00-PLAN.md +0 -91
  133. package/src/tools/VideoPlayer/@refactoring/01-TYPES.md +0 -284
  134. package/src/tools/VideoPlayer/@refactoring/02-UTILS.md +0 -141
  135. package/src/tools/VideoPlayer/@refactoring/03-HOOKS.md +0 -178
  136. package/src/tools/VideoPlayer/@refactoring/04-COMPONENTS.md +0 -95
  137. package/src/tools/VideoPlayer/@refactoring/05-EXECUTION-CHECKLIST.md +0 -139
  138. package/src/tools/VideoPlayer/README.md +0 -264
  139. package/src/tools/VideoPlayer/components/VideoControls.tsx +0 -138
  140. package/src/tools/VideoPlayer/components/VideoErrorFallback.tsx +0 -174
  141. package/src/tools/VideoPlayer/components/VideoPlayer.tsx +0 -201
  142. package/src/tools/VideoPlayer/components/index.ts +0 -14
  143. package/src/tools/VideoPlayer/context/VideoPlayerContext.tsx +0 -52
  144. package/src/tools/VideoPlayer/context/index.ts +0 -8
  145. package/src/tools/VideoPlayer/hooks/index.ts +0 -12
  146. package/src/tools/VideoPlayer/hooks/useVideoPlayerSettings.ts +0 -70
  147. package/src/tools/VideoPlayer/hooks/useVideoPositionCache.ts +0 -116
  148. package/src/tools/VideoPlayer/index.ts +0 -77
  149. package/src/tools/VideoPlayer/providers/NativeProvider.tsx +0 -284
  150. package/src/tools/VideoPlayer/providers/StreamProvider.tsx +0 -505
  151. package/src/tools/VideoPlayer/providers/VidstackProvider.tsx +0 -400
  152. package/src/tools/VideoPlayer/providers/index.ts +0 -8
  153. package/src/tools/VideoPlayer/types/index.ts +0 -38
  154. package/src/tools/VideoPlayer/types/player.ts +0 -116
  155. package/src/tools/VideoPlayer/types/provider.ts +0 -93
  156. package/src/tools/VideoPlayer/types/sources.ts +0 -97
  157. package/src/tools/VideoPlayer/utils/debug.ts +0 -14
  158. package/src/tools/VideoPlayer/utils/fileSource.ts +0 -78
  159. package/src/tools/VideoPlayer/utils/index.ts +0 -12
  160. package/src/tools/VideoPlayer/utils/resolvers.ts +0 -75
  161. package/src/tools/index.ts +0 -170
@@ -1,74 +0,0 @@
1
- "use client"
2
-
3
- import { Plus } from 'lucide-react';
4
- import React from 'react';
5
-
6
- import { Button } from '@djangocfg/ui-core/components';
7
- import { ArrayFieldTemplateProps } from '@rjsf/utils';
8
-
9
- /**
10
- * Array field template for JSON Schema Form
11
- * Renders array items with add/remove controls
12
- *
13
- * NOTE: In RJSF v6, `items` is an array of ReactElement (already rendered),
14
- * NOT an array of objects with {children, hasRemove, etc.}.
15
- * The actual rendering of each item (including remove buttons) is handled
16
- * by ArrayFieldItemTemplate.
17
- */
18
- export function ArrayFieldTemplate(props: ArrayFieldTemplateProps) {
19
- const {
20
- title,
21
- items,
22
- canAdd,
23
- onAddClick,
24
- required,
25
- } = props;
26
-
27
- return (
28
- <div className="space-y-4">
29
- {title && (
30
- <div className="flex items-center justify-between">
31
- <h3 className="text-lg font-semibold">
32
- {title}
33
- {required && <span className="text-destructive ml-1">*</span>}
34
- </h3>
35
- {canAdd && (
36
- <Button
37
- type="button"
38
- variant="outline"
39
- size="sm"
40
- onClick={onAddClick}
41
- className="gap-2"
42
- >
43
- <Plus className="h-4 w-4" />
44
- Add Item
45
- </Button>
46
- )}
47
- </div>
48
- )}
49
-
50
- {/* In RJSF v6, items is already an array of ReactElements */}
51
- <div className="space-y-3">
52
- {items}
53
- </div>
54
-
55
- {items.length === 0 && (
56
- <div className="text-center py-8 text-muted-foreground border-2 border-dashed rounded-md">
57
- No items added yet.
58
- {canAdd && (
59
- <Button
60
- type="button"
61
- variant="ghost"
62
- size="sm"
63
- onClick={onAddClick}
64
- className="mt-2 gap-2"
65
- >
66
- <Plus className="h-4 w-4" />
67
- Add First Item
68
- </Button>
69
- )}
70
- </div>
71
- )}
72
- </div>
73
- );
74
- }
@@ -1,107 +0,0 @@
1
- "use client"
2
-
3
- import React, { ChangeEvent, FocusEvent, useCallback, useMemo } from 'react';
4
-
5
- import { Input } from '@djangocfg/ui-core/components';
6
- import { getInputProps, WidgetProps } from '@rjsf/utils';
7
-
8
- /**
9
- * Base input template for JSON Schema Form
10
- *
11
- * This template is CRITICAL for rendering primitive types (string, number)
12
- * inside arrays. Without it, array items with primitive types will render
13
- * as empty containers.
14
- *
15
- * RJSF uses this template for:
16
- * - Array items with primitive types (e.g., array of strings)
17
- * - Fields without explicit widget mapping
18
- * - All text-based widgets internally
19
- *
20
- * @see https://rjsf-team.github.io/react-jsonschema-form/docs/advanced-customization/custom-templates/#baseinputtemplate
21
- */
22
- export function BaseInputTemplate(props: WidgetProps) {
23
- const {
24
- id,
25
- type,
26
- value,
27
- readonly,
28
- disabled,
29
- autofocus,
30
- onBlur,
31
- onFocus,
32
- onChange,
33
- options,
34
- schema,
35
- rawErrors,
36
- placeholder,
37
- } = props;
38
-
39
- // Get input props from RJSF utils (handles step, min, max, etc.)
40
- const inputProps = useMemo(() => {
41
- return getInputProps(schema, type, options);
42
- }, [schema, type, options]);
43
-
44
- // Safely convert value to string for input
45
- const safeValue = useMemo(() => {
46
- if (value === null || value === undefined) return '';
47
- return String(value);
48
- }, [value]);
49
-
50
- const hasError = useMemo(() => {
51
- return rawErrors && rawErrors.length > 0;
52
- }, [rawErrors]);
53
-
54
- // Handle text change - transform empty strings based on schema type
55
- const handleChange = useCallback((event: ChangeEvent<HTMLInputElement>) => {
56
- const val = event.target.value;
57
-
58
- // Empty value handling
59
- if (val === '') {
60
- onChange(options?.emptyValue ?? '');
61
- return;
62
- }
63
-
64
- // Number type conversion
65
- if (inputProps.type === 'number' || schema.type === 'number' || schema.type === 'integer') {
66
- const num = Number(val);
67
- onChange(isNaN(num) ? val : num);
68
- return;
69
- }
70
-
71
- onChange(val);
72
- }, [onChange, inputProps.type, schema.type, options?.emptyValue]);
73
-
74
- const handleBlur = useCallback((event: FocusEvent<HTMLInputElement>) => {
75
- onBlur(id, event.target.value);
76
- }, [id, onBlur]);
77
-
78
- const handleFocus = useCallback((event: FocusEvent<HTMLInputElement>) => {
79
- onFocus(id, event.target.value);
80
- }, [id, onFocus]);
81
-
82
- // Determine input type
83
- const inputType = useMemo(() => {
84
- if (inputProps.type) return inputProps.type;
85
- if (schema.type === 'number' || schema.type === 'integer') return 'number';
86
- return 'text';
87
- }, [inputProps.type, schema.type]);
88
-
89
- return (
90
- <Input
91
- id={id}
92
- type={inputType}
93
- value={safeValue}
94
- disabled={disabled}
95
- readOnly={readonly}
96
- autoFocus={autofocus}
97
- onChange={handleChange}
98
- onBlur={handleBlur}
99
- onFocus={handleFocus}
100
- placeholder={placeholder}
101
- className={hasError ? 'border-destructive' : ''}
102
- step={inputProps.step}
103
- min={inputProps.min}
104
- max={inputProps.max}
105
- />
106
- );
107
- }
@@ -1,35 +0,0 @@
1
- "use client"
2
-
3
- import { AlertCircle } from 'lucide-react';
4
- import React from 'react';
5
-
6
- import { Alert, AlertDescription, AlertTitle } from '@djangocfg/ui-core/components';
7
- import { ErrorListProps } from '@rjsf/utils';
8
-
9
- /**
10
- * Error list template for JSON Schema Form
11
- * Displays validation errors at the top of the form
12
- */
13
- export function ErrorListTemplate(props: ErrorListProps) {
14
- const { errors } = props;
15
-
16
- if (!errors || errors.length === 0) {
17
- return null;
18
- }
19
-
20
- return (
21
- <Alert variant="destructive" className="mb-6">
22
- <AlertCircle className="h-4 w-4" />
23
- <AlertTitle>Validation Errors</AlertTitle>
24
- <AlertDescription>
25
- <ul className="list-disc list-inside space-y-1 mt-2">
26
- {errors.map((error, index) => (
27
- <li key={index} className="text-sm">
28
- {error.stack}
29
- </li>
30
- ))}
31
- </ul>
32
- </AlertDescription>
33
- </Alert>
34
- );
35
- }
@@ -1,62 +0,0 @@
1
- "use client"
2
-
3
- import React from 'react';
4
-
5
- import { Label } from '@djangocfg/ui-core/components';
6
- import { cn } from '@djangocfg/ui-core/lib';
7
- import { FieldTemplateProps } from '@rjsf/utils';
8
-
9
- /**
10
- * Field template for JSON Schema Form
11
- * Controls the layout and styling of individual form fields
12
- */
13
- export function FieldTemplate(props: FieldTemplateProps) {
14
- const {
15
- id,
16
- classNames,
17
- style,
18
- label,
19
- help,
20
- required,
21
- description,
22
- errors,
23
- children,
24
- displayLabel,
25
- hidden,
26
- rawErrors,
27
- } = props;
28
-
29
- if (hidden) {
30
- return <div className="hidden">{children}</div>;
31
- }
32
-
33
- const hasError = rawErrors && rawErrors.length > 0;
34
-
35
- return (
36
- <div
37
- className={cn('space-y-2', classNames)}
38
- style={style}
39
- >
40
- {displayLabel && label && (
41
- <Label htmlFor={id} className={cn(hasError && 'text-destructive')}>
42
- {label}
43
- {required && <span className="text-destructive ml-1">*</span>}
44
- </Label>
45
- )}
46
-
47
- {description && (
48
- <div className="text-sm text-muted-foreground">{description}</div>
49
- )}
50
-
51
- <div>{children}</div>
52
-
53
- {errors && (
54
- <div className="text-sm text-destructive">{errors}</div>
55
- )}
56
-
57
- {help && (
58
- <div className="text-sm text-muted-foreground">{help}</div>
59
- )}
60
- </div>
61
- );
62
- }
@@ -1,116 +0,0 @@
1
- "use client"
2
-
3
- import { ChevronDown } from 'lucide-react';
4
- import React, { useState } from 'react';
5
-
6
- import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@djangocfg/ui-core/components';
7
- import { cn } from '@djangocfg/ui-core/lib';
8
- import { ObjectFieldTemplateProps } from '@rjsf/utils';
9
-
10
- /**
11
- * Object field template for JSON Schema Form
12
- *
13
- * Supports:
14
- * - Collapsible groups via ui:collapsible option
15
- * - Grid layout via ui:grid option
16
- * - Custom styling via ui:className
17
- *
18
- * Usage in uiSchema:
19
- * ```json
20
- * {
21
- * "colors": {
22
- * "ui:collapsible": true,
23
- * "ui:collapsed": false,
24
- * "ui:grid": 2
25
- * }
26
- * }
27
- * ```
28
- */
29
- export function ObjectFieldTemplate(props: ObjectFieldTemplateProps) {
30
- const {
31
- title,
32
- description,
33
- properties,
34
- required,
35
- uiSchema,
36
- } = props;
37
-
38
- // UI options
39
- const isCollapsible = uiSchema?.['ui:collapsible'] === true;
40
- const defaultCollapsed = uiSchema?.['ui:collapsed'] === true;
41
- const gridCols = uiSchema?.['ui:grid'] as number | undefined;
42
- const className = uiSchema?.['ui:className'] as string | undefined;
43
-
44
- // Collapsible state
45
- const [isOpen, setIsOpen] = useState(!defaultCollapsed);
46
-
47
- // Check if this is root object (no title usually means root)
48
- const isRoot = !title;
49
-
50
- // Grid class based on columns
51
- const gridClass = gridCols
52
- ? `grid gap-4 grid-cols-${gridCols}`
53
- : 'space-y-4';
54
-
55
- // Content wrapper
56
- const content = (
57
- <div className={cn(gridClass, className)}>
58
- {properties.map((element) => (
59
- <div key={element.name} className="property-wrapper">
60
- {element.content}
61
- </div>
62
- ))}
63
- </div>
64
- );
65
-
66
- // Root object - no wrapper
67
- if (isRoot) {
68
- return <div className="space-y-6">{content}</div>;
69
- }
70
-
71
- // Collapsible group
72
- if (isCollapsible) {
73
- return (
74
- <Collapsible open={isOpen} onOpenChange={setIsOpen} className="space-y-2">
75
- <CollapsibleTrigger className="flex w-full items-center justify-between rounded-lg border bg-muted/50 px-4 py-3 text-left hover:bg-muted transition-colors">
76
- <div>
77
- <h3 className="text-sm font-semibold">
78
- {title}
79
- {required && <span className="text-destructive ml-1">*</span>}
80
- </h3>
81
- {description && (
82
- <p className="text-xs text-muted-foreground mt-0.5">{description}</p>
83
- )}
84
- </div>
85
- <ChevronDown
86
- className={cn(
87
- 'h-4 w-4 text-muted-foreground transition-transform duration-200',
88
- isOpen && 'rotate-180'
89
- )}
90
- />
91
- </CollapsibleTrigger>
92
- <CollapsibleContent className="pl-1 pr-1 pt-2">
93
- {content}
94
- </CollapsibleContent>
95
- </Collapsible>
96
- );
97
- }
98
-
99
- // Regular group with title
100
- return (
101
- <div className="space-y-4">
102
- {title && (
103
- <div className="border-b pb-2">
104
- <h3 className="text-sm font-semibold">
105
- {title}
106
- {required && <span className="text-destructive ml-1">*</span>}
107
- </h3>
108
- {description && (
109
- <p className="text-xs text-muted-foreground mt-1">{description}</p>
110
- )}
111
- </div>
112
- )}
113
- {content}
114
- </div>
115
- );
116
- }
@@ -1,12 +0,0 @@
1
- /**
2
- * Custom templates for JSON Schema Form
3
- *
4
- * Templates control the layout and structure of form sections
5
- */
6
-
7
- export { FieldTemplate } from './FieldTemplate';
8
- export { ObjectFieldTemplate } from './ObjectFieldTemplate';
9
- export { ArrayFieldTemplate } from './ArrayFieldTemplate';
10
- export { ArrayFieldItemTemplate } from './ArrayFieldItemTemplate';
11
- export { ErrorListTemplate } from './ErrorListTemplate';
12
- export { BaseInputTemplate } from './BaseInputTemplate';
@@ -1,83 +0,0 @@
1
- import type { RJSFSchema, UiSchema } from '@rjsf/utils';
2
- import type { IChangeEvent, FormProps } from '@rjsf/core';
3
-
4
- /**
5
- * JSON Schema Form props interface
6
- */
7
- export interface JsonSchemaFormProps<T = any> extends Partial<FormProps<T>> {
8
- /** JSON Schema that defines the form structure */
9
- schema: RJSFSchema;
10
-
11
- /** UI Schema for customizing the form appearance */
12
- uiSchema?: UiSchema;
13
-
14
- /** Initial form data */
15
- formData?: T;
16
-
17
- /** Callback when form is submitted */
18
- onSubmit?: (data: IChangeEvent<T>) => void;
19
-
20
- /** Callback when form data changes */
21
- onChange?: (data: IChangeEvent<T>) => void;
22
-
23
- /** Callback when form has validation errors */
24
- onError?: (errors: any[]) => void;
25
-
26
- /** Whether to show error list at the top of form */
27
- showErrorList?: false | 'top' | 'bottom';
28
-
29
- /** Whether to live validate on change */
30
- liveValidate?: boolean;
31
-
32
- /** Whether the form is disabled */
33
- disabled?: boolean;
34
-
35
- /** Whether the form is read-only */
36
- readonly?: boolean;
37
-
38
- /** Custom CSS class name */
39
- className?: string;
40
-
41
- /** Whether to show submit button */
42
- showSubmitButton?: boolean;
43
-
44
- /** Submit button text */
45
- submitButtonText?: string;
46
- }
47
-
48
- /**
49
- * Field template props
50
- */
51
- export interface FieldTemplateProps {
52
- id: string;
53
- label: string;
54
- required: boolean;
55
- description?: string;
56
- errors?: any;
57
- help?: string;
58
- displayLabel?: boolean;
59
- children: React.ReactNode;
60
- classNames?: string;
61
- rawErrors?: string[];
62
- schema: RJSFSchema;
63
- }
64
-
65
- /**
66
- * Widget props base interface
67
- */
68
- export interface BaseWidgetProps {
69
- id: string;
70
- value: any;
71
- required: boolean;
72
- disabled: boolean;
73
- readonly: boolean;
74
- autofocus: boolean;
75
- onChange: (value: any) => void;
76
- onBlur: (id: string, value: any) => void;
77
- onFocus: (id: string, value: any) => void;
78
- options: any;
79
- schema: RJSFSchema;
80
- label: string;
81
- placeholder?: string;
82
- rawErrors?: string[];
83
- }
@@ -1,213 +0,0 @@
1
- import consola from 'consola';
2
-
3
- import { RJSFSchema } from '@rjsf/utils';
4
-
5
- /**
6
- * Utility functions for JSON Schema Form
7
- */
8
-
9
- /**
10
- * Safely validates and normalizes JSON Schema
11
- * Ensures schema is valid before rendering
12
- */
13
- export function validateSchema(schema: any): RJSFSchema | null {
14
- if (!schema || typeof schema !== 'object') {
15
- if (process.env.NODE_ENV === 'development') {
16
- consola.error('[JsonSchemaForm] Invalid schema: must be an object', schema);
17
- }
18
- return null;
19
- }
20
-
21
- // Basic schema validation - more permissive
22
- // Schema is valid if it has type OR properties OR $ref OR $schema
23
- const hasValidStructure =
24
- schema.type ||
25
- schema.properties ||
26
- schema.$ref ||
27
- schema.$schema;
28
-
29
- if (!hasValidStructure) {
30
- if (process.env.NODE_ENV === 'development') {
31
- consola.error('[JsonSchemaForm] Invalid schema: missing type, properties, $ref, or $schema', schema);
32
- }
33
- return null;
34
- }
35
-
36
- if (process.env.NODE_ENV === 'development') {
37
- consola.success('[JsonSchemaForm] Schema validated successfully:', {
38
- type: schema.type,
39
- title: schema.title,
40
- hasProperties: !!schema.properties,
41
- hasRequired: !!schema.required,
42
- });
43
- }
44
-
45
- return schema as RJSFSchema;
46
- }
47
-
48
- /**
49
- * Safely normalizes form data
50
- * Removes undefined values and ensures data structure matches schema
51
- */
52
- export function normalizeFormData<T = any>(
53
- formData: any,
54
- schema: RJSFSchema
55
- ): T {
56
- if (formData === null || formData === undefined) {
57
- return (schema.type === 'object' ? {} : schema.type === 'array' ? [] : null) as T;
58
- }
59
-
60
- // Deep clone to avoid mutations
61
- const normalized = JSON.parse(JSON.stringify(formData));
62
-
63
- // Remove undefined values recursively
64
- return removeUndefined(normalized) as T;
65
- }
66
-
67
- /**
68
- * Recursively removes undefined values from an object
69
- */
70
- function removeUndefined(obj: any): any {
71
- if (obj === null || obj === undefined) {
72
- return obj;
73
- }
74
-
75
- if (Array.isArray(obj)) {
76
- return obj.map(removeUndefined).filter((item) => item !== undefined);
77
- }
78
-
79
- if (typeof obj === 'object') {
80
- const cleaned: any = {};
81
- for (const key in obj) {
82
- if (obj[key] !== undefined) {
83
- cleaned[key] = removeUndefined(obj[key]);
84
- }
85
- }
86
- return cleaned;
87
- }
88
-
89
- return obj;
90
- }
91
-
92
- /**
93
- * Merges schema defaults with form data
94
- */
95
- export function mergeDefaults(
96
- formData: any,
97
- schema: RJSFSchema
98
- ): any {
99
- if (!schema) return formData;
100
-
101
- const result = { ...formData };
102
-
103
- if (schema.type === 'object' && schema.properties) {
104
- for (const [key, propSchema] of Object.entries(schema.properties)) {
105
- const prop = propSchema as RJSFSchema;
106
-
107
- // Apply default if field is missing
108
- if (result[key] === undefined && prop.default !== undefined) {
109
- result[key] = prop.default;
110
- }
111
-
112
- // Recursively merge nested objects
113
- if (prop.type === 'object' && result[key]) {
114
- result[key] = mergeDefaults(result[key], prop);
115
- }
116
- }
117
- }
118
-
119
- return result;
120
- }
121
-
122
- /**
123
- * Safely parses JSON string with error handling
124
- */
125
- export function safeJsonParse<T = any>(
126
- jsonString: string,
127
- fallback: T
128
- ): T {
129
- try {
130
- return JSON.parse(jsonString);
131
- } catch (error) {
132
- consola.error('[JsonSchemaForm] JSON parse error:', error);
133
- return fallback;
134
- }
135
- }
136
-
137
- /**
138
- * Safely stringifies object to JSON
139
- */
140
- export function safeJsonStringify(
141
- obj: any,
142
- pretty: boolean = true
143
- ): string {
144
- try {
145
- return JSON.stringify(obj, null, pretty ? 2 : 0);
146
- } catch (error) {
147
- consola.error('[JsonSchemaForm] JSON stringify error:', error);
148
- return '{}';
149
- }
150
- }
151
-
152
- /**
153
- * Checks if schema has required fields
154
- */
155
- export function hasRequiredFields(schema: RJSFSchema): boolean {
156
- return Array.isArray(schema.required) && schema.required.length > 0;
157
- }
158
-
159
- /**
160
- * Gets all required field paths from schema
161
- */
162
- export function getRequiredFields(
163
- schema: RJSFSchema,
164
- prefix: string = ''
165
- ): string[] {
166
- const required: string[] = [];
167
-
168
- if (schema.required && Array.isArray(schema.required)) {
169
- required.push(...schema.required.map((field) =>
170
- prefix ? `${prefix}.${field}` : field
171
- ));
172
- }
173
-
174
- if (schema.type === 'object' && schema.properties) {
175
- for (const [key, propSchema] of Object.entries(schema.properties)) {
176
- const prop = propSchema as RJSFSchema;
177
- const fieldPath = prefix ? `${prefix}.${key}` : key;
178
- required.push(...getRequiredFields(prop, fieldPath));
179
- }
180
- }
181
-
182
- return required;
183
- }
184
-
185
- /**
186
- * Validates form data against required fields
187
- */
188
- export function validateRequiredFields(
189
- formData: any,
190
- schema: RJSFSchema
191
- ): { valid: boolean; missing: string[] } {
192
- const requiredFields = getRequiredFields(schema);
193
- const missing: string[] = [];
194
-
195
- for (const field of requiredFields) {
196
- const value = getNestedValue(formData, field);
197
- if (value === undefined || value === null || value === '') {
198
- missing.push(field);
199
- }
200
- }
201
-
202
- return {
203
- valid: missing.length === 0,
204
- missing,
205
- };
206
- }
207
-
208
- /**
209
- * Gets nested value from object by path
210
- */
211
- function getNestedValue(obj: any, path: string): any {
212
- return path.split('.').reduce((current, key) => current?.[key], obj);
213
- }