@djangocfg/ui-tools 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 (174) hide show
  1. package/dist/LottiePlayer.client-LBEC2JKY.mjs +161 -0
  2. package/dist/LottiePlayer.client-LBEC2JKY.mjs.map +1 -0
  3. package/dist/LottiePlayer.client-WFMG2OOW.cjs +168 -0
  4. package/dist/LottiePlayer.client-WFMG2OOW.cjs.map +1 -0
  5. package/dist/Mermaid.client-4TU2TSH3.mjs +477 -0
  6. package/dist/Mermaid.client-4TU2TSH3.mjs.map +1 -0
  7. package/dist/Mermaid.client-SBYY364Q.cjs +483 -0
  8. package/dist/Mermaid.client-SBYY364Q.cjs.map +1 -0
  9. package/dist/PlaygroundLayout-3YVSAEAF.cjs +1003 -0
  10. package/dist/PlaygroundLayout-3YVSAEAF.cjs.map +1 -0
  11. package/dist/PlaygroundLayout-4DYBORAS.mjs +996 -0
  12. package/dist/PlaygroundLayout-4DYBORAS.mjs.map +1 -0
  13. package/dist/PrettyCode.client-LCBPPTIX.mjs +152 -0
  14. package/dist/PrettyCode.client-LCBPPTIX.mjs.map +1 -0
  15. package/dist/PrettyCode.client-PNPLXRH6.cjs +154 -0
  16. package/dist/PrettyCode.client-PNPLXRH6.cjs.map +1 -0
  17. package/dist/chunk-37ZI6VD4.mjs +12 -0
  18. package/dist/chunk-37ZI6VD4.mjs.map +1 -0
  19. package/dist/chunk-3HK2OE62.cjs +81 -0
  20. package/dist/chunk-3HK2OE62.cjs.map +1 -0
  21. package/dist/chunk-7DGDQVQW.cjs +591 -0
  22. package/dist/chunk-7DGDQVQW.cjs.map +1 -0
  23. package/dist/chunk-M6P2FU7L.mjs +572 -0
  24. package/dist/chunk-M6P2FU7L.mjs.map +1 -0
  25. package/dist/chunk-UQ3XI5MY.cjs +15 -0
  26. package/dist/chunk-UQ3XI5MY.cjs.map +1 -0
  27. package/dist/chunk-YFRNE2IR.mjs +79 -0
  28. package/dist/chunk-YFRNE2IR.mjs.map +1 -0
  29. package/dist/index.cjs +5042 -0
  30. package/dist/index.cjs.map +1 -0
  31. package/dist/index.d.cts +1591 -0
  32. package/dist/index.d.ts +1591 -0
  33. package/dist/index.mjs +4941 -0
  34. package/dist/index.mjs.map +1 -0
  35. package/package.json +86 -0
  36. package/src/components/markdown/MarkdownMessage.tsx +340 -0
  37. package/src/components/markdown/index.ts +5 -0
  38. package/src/index.ts +26 -0
  39. package/src/stores/index.ts +9 -0
  40. package/src/stores/mediaCache.ts +534 -0
  41. package/src/tools/AudioPlayer/README.md +206 -0
  42. package/src/tools/AudioPlayer/components/HybridAudioPlayer.tsx +216 -0
  43. package/src/tools/AudioPlayer/components/HybridSimplePlayer.tsx +280 -0
  44. package/src/tools/AudioPlayer/components/HybridWaveform.tsx +279 -0
  45. package/src/tools/AudioPlayer/components/ReactiveCover/AudioReactiveCover.tsx +149 -0
  46. package/src/tools/AudioPlayer/components/ReactiveCover/effects/GlowEffect.tsx +110 -0
  47. package/src/tools/AudioPlayer/components/ReactiveCover/effects/MeshEffect.tsx +58 -0
  48. package/src/tools/AudioPlayer/components/ReactiveCover/effects/OrbsEffect.tsx +45 -0
  49. package/src/tools/AudioPlayer/components/ReactiveCover/effects/SpotlightEffect.tsx +82 -0
  50. package/src/tools/AudioPlayer/components/ReactiveCover/effects/index.ts +8 -0
  51. package/src/tools/AudioPlayer/components/ReactiveCover/index.ts +6 -0
  52. package/src/tools/AudioPlayer/components/index.ts +22 -0
  53. package/src/tools/AudioPlayer/context/HybridAudioProvider.tsx +158 -0
  54. package/src/tools/AudioPlayer/context/index.ts +16 -0
  55. package/src/tools/AudioPlayer/effects/index.ts +412 -0
  56. package/src/tools/AudioPlayer/hooks/index.ts +35 -0
  57. package/src/tools/AudioPlayer/hooks/useHybridAudio.ts +387 -0
  58. package/src/tools/AudioPlayer/hooks/useHybridAudioAnalysis.ts +95 -0
  59. package/src/tools/AudioPlayer/hooks/useVisualization.tsx +207 -0
  60. package/src/tools/AudioPlayer/index.ts +133 -0
  61. package/src/tools/AudioPlayer/types/effects.ts +73 -0
  62. package/src/tools/AudioPlayer/types/index.ts +27 -0
  63. package/src/tools/AudioPlayer/utils/debug.ts +14 -0
  64. package/src/tools/AudioPlayer/utils/formatTime.ts +10 -0
  65. package/src/tools/AudioPlayer/utils/index.ts +6 -0
  66. package/src/tools/ImageViewer/@refactoring/00-PLAN.md +71 -0
  67. package/src/tools/ImageViewer/@refactoring/01-TYPES.md +121 -0
  68. package/src/tools/ImageViewer/@refactoring/02-UTILS.md +143 -0
  69. package/src/tools/ImageViewer/@refactoring/03-HOOKS.md +261 -0
  70. package/src/tools/ImageViewer/@refactoring/04-COMPONENTS.md +427 -0
  71. package/src/tools/ImageViewer/@refactoring/05-EXECUTION-CHECKLIST.md +126 -0
  72. package/src/tools/ImageViewer/README.md +200 -0
  73. package/src/tools/ImageViewer/components/ImageInfo.tsx +44 -0
  74. package/src/tools/ImageViewer/components/ImageToolbar.tsx +145 -0
  75. package/src/tools/ImageViewer/components/ImageViewer.tsx +241 -0
  76. package/src/tools/ImageViewer/components/index.ts +7 -0
  77. package/src/tools/ImageViewer/hooks/index.ts +9 -0
  78. package/src/tools/ImageViewer/hooks/useImageLoading.ts +204 -0
  79. package/src/tools/ImageViewer/hooks/useImageTransform.ts +101 -0
  80. package/src/tools/ImageViewer/index.ts +60 -0
  81. package/src/tools/ImageViewer/types.ts +81 -0
  82. package/src/tools/ImageViewer/utils/constants.ts +59 -0
  83. package/src/tools/ImageViewer/utils/debug.ts +14 -0
  84. package/src/tools/ImageViewer/utils/index.ts +17 -0
  85. package/src/tools/ImageViewer/utils/lqip.ts +47 -0
  86. package/src/tools/JsonForm/JsonSchemaForm.tsx +197 -0
  87. package/src/tools/JsonForm/examples/BotConfigExample.tsx +249 -0
  88. package/src/tools/JsonForm/examples/RealBotConfigExample.tsx +161 -0
  89. package/src/tools/JsonForm/index.ts +46 -0
  90. package/src/tools/JsonForm/templates/ArrayFieldItemTemplate.tsx +47 -0
  91. package/src/tools/JsonForm/templates/ArrayFieldTemplate.tsx +74 -0
  92. package/src/tools/JsonForm/templates/BaseInputTemplate.tsx +107 -0
  93. package/src/tools/JsonForm/templates/ErrorListTemplate.tsx +35 -0
  94. package/src/tools/JsonForm/templates/FieldTemplate.tsx +62 -0
  95. package/src/tools/JsonForm/templates/ObjectFieldTemplate.tsx +116 -0
  96. package/src/tools/JsonForm/templates/index.ts +12 -0
  97. package/src/tools/JsonForm/types.ts +83 -0
  98. package/src/tools/JsonForm/utils.ts +213 -0
  99. package/src/tools/JsonForm/widgets/CheckboxWidget.tsx +37 -0
  100. package/src/tools/JsonForm/widgets/ColorWidget.tsx +219 -0
  101. package/src/tools/JsonForm/widgets/NumberWidget.tsx +89 -0
  102. package/src/tools/JsonForm/widgets/SelectWidget.tsx +97 -0
  103. package/src/tools/JsonForm/widgets/SliderWidget.tsx +148 -0
  104. package/src/tools/JsonForm/widgets/SwitchWidget.tsx +35 -0
  105. package/src/tools/JsonForm/widgets/TextWidget.tsx +96 -0
  106. package/src/tools/JsonForm/widgets/index.ts +14 -0
  107. package/src/tools/JsonTree/index.tsx +243 -0
  108. package/src/tools/LottiePlayer/LottiePlayer.client.tsx +213 -0
  109. package/src/tools/LottiePlayer/index.tsx +56 -0
  110. package/src/tools/LottiePlayer/types.ts +108 -0
  111. package/src/tools/LottiePlayer/useLottie.ts +164 -0
  112. package/src/tools/Mermaid/Mermaid.client.tsx +82 -0
  113. package/src/tools/Mermaid/components/MermaidCodeViewer.tsx +95 -0
  114. package/src/tools/Mermaid/components/MermaidFullscreenModal.tsx +103 -0
  115. package/src/tools/Mermaid/hooks/index.ts +4 -0
  116. package/src/tools/Mermaid/hooks/useMermaidCleanup.ts +73 -0
  117. package/src/tools/Mermaid/hooks/useMermaidFullscreen.ts +46 -0
  118. package/src/tools/Mermaid/hooks/useMermaidRenderer.ts +226 -0
  119. package/src/tools/Mermaid/hooks/useMermaidValidation.ts +29 -0
  120. package/src/tools/Mermaid/index.tsx +44 -0
  121. package/src/tools/Mermaid/utils/mermaid-helpers.ts +33 -0
  122. package/src/tools/OpenapiViewer/components/EndpointInfo.tsx +149 -0
  123. package/src/tools/OpenapiViewer/components/EndpointsLibrary.tsx +263 -0
  124. package/src/tools/OpenapiViewer/components/PlaygroundLayout.tsx +125 -0
  125. package/src/tools/OpenapiViewer/components/PlaygroundStepper.tsx +100 -0
  126. package/src/tools/OpenapiViewer/components/RequestBuilder.tsx +157 -0
  127. package/src/tools/OpenapiViewer/components/RequestParametersForm.tsx +253 -0
  128. package/src/tools/OpenapiViewer/components/ResponseViewer.tsx +173 -0
  129. package/src/tools/OpenapiViewer/components/VersionSelector.tsx +68 -0
  130. package/src/tools/OpenapiViewer/components/index.ts +14 -0
  131. package/src/tools/OpenapiViewer/constants.ts +39 -0
  132. package/src/tools/OpenapiViewer/context/PlaygroundContext.tsx +337 -0
  133. package/src/tools/OpenapiViewer/hooks/index.ts +8 -0
  134. package/src/tools/OpenapiViewer/hooks/useMobile.ts +10 -0
  135. package/src/tools/OpenapiViewer/hooks/useOpenApiSchema.ts +199 -0
  136. package/src/tools/OpenapiViewer/index.tsx +37 -0
  137. package/src/tools/OpenapiViewer/types.ts +151 -0
  138. package/src/tools/OpenapiViewer/utils/apiKeyManager.ts +149 -0
  139. package/src/tools/OpenapiViewer/utils/formatters.ts +71 -0
  140. package/src/tools/OpenapiViewer/utils/index.ts +9 -0
  141. package/src/tools/OpenapiViewer/utils/versionManager.ts +161 -0
  142. package/src/tools/PrettyCode/PrettyCode.client.tsx +208 -0
  143. package/src/tools/PrettyCode/index.tsx +47 -0
  144. package/src/tools/VideoPlayer/@refactoring/00-PLAN.md +91 -0
  145. package/src/tools/VideoPlayer/@refactoring/01-TYPES.md +284 -0
  146. package/src/tools/VideoPlayer/@refactoring/02-UTILS.md +141 -0
  147. package/src/tools/VideoPlayer/@refactoring/03-HOOKS.md +178 -0
  148. package/src/tools/VideoPlayer/@refactoring/04-COMPONENTS.md +95 -0
  149. package/src/tools/VideoPlayer/@refactoring/05-EXECUTION-CHECKLIST.md +139 -0
  150. package/src/tools/VideoPlayer/README.md +264 -0
  151. package/src/tools/VideoPlayer/components/VideoControls.tsx +138 -0
  152. package/src/tools/VideoPlayer/components/VideoErrorFallback.tsx +172 -0
  153. package/src/tools/VideoPlayer/components/VideoPlayer.tsx +201 -0
  154. package/src/tools/VideoPlayer/components/index.ts +14 -0
  155. package/src/tools/VideoPlayer/context/VideoPlayerContext.tsx +52 -0
  156. package/src/tools/VideoPlayer/context/index.ts +8 -0
  157. package/src/tools/VideoPlayer/hooks/index.ts +12 -0
  158. package/src/tools/VideoPlayer/hooks/useVideoPlayerSettings.ts +70 -0
  159. package/src/tools/VideoPlayer/hooks/useVideoPositionCache.ts +116 -0
  160. package/src/tools/VideoPlayer/index.ts +77 -0
  161. package/src/tools/VideoPlayer/providers/NativeProvider.tsx +284 -0
  162. package/src/tools/VideoPlayer/providers/StreamProvider.tsx +505 -0
  163. package/src/tools/VideoPlayer/providers/VidstackProvider.tsx +400 -0
  164. package/src/tools/VideoPlayer/providers/index.ts +8 -0
  165. package/src/tools/VideoPlayer/types/index.ts +38 -0
  166. package/src/tools/VideoPlayer/types/player.ts +116 -0
  167. package/src/tools/VideoPlayer/types/provider.ts +93 -0
  168. package/src/tools/VideoPlayer/types/sources.ts +97 -0
  169. package/src/tools/VideoPlayer/utils/debug.ts +14 -0
  170. package/src/tools/VideoPlayer/utils/fileSource.ts +78 -0
  171. package/src/tools/VideoPlayer/utils/index.ts +12 -0
  172. package/src/tools/VideoPlayer/utils/resolvers.ts +75 -0
  173. package/src/tools/_shared.ts +29 -0
  174. package/src/tools/index.ts +172 -0
@@ -0,0 +1,197 @@
1
+ 'use client';
2
+
3
+ import consola from 'consola';
4
+ import { AlertCircle } from 'lucide-react';
5
+ import React, { useCallback, useMemo } from 'react';
6
+
7
+ import { Alert, AlertDescription, Button } from '@djangocfg/ui-core/components';
8
+ import Form from '@rjsf/core';
9
+ import { RegistryWidgetsType } from '@rjsf/utils';
10
+ import validator from '@rjsf/validator-ajv8';
11
+
12
+ import {
13
+ ArrayFieldItemTemplate, ArrayFieldTemplate, BaseInputTemplate, ErrorListTemplate, FieldTemplate,
14
+ ObjectFieldTemplate
15
+ } from './templates';
16
+ import { JsonSchemaFormProps } from './types';
17
+ import { normalizeFormData, validateSchema } from './utils';
18
+ import {
19
+ CheckboxWidget, ColorWidget, NumberWidget, SelectWidget, SliderWidget, SwitchWidget, TextWidget
20
+ } from './widgets';
21
+
22
+ /**
23
+ * JSON Schema Form Component
24
+ *
25
+ * A fully-featured form generator that creates forms from JSON Schema.
26
+ * Built on top of react-jsonschema-form with custom widgets and templates
27
+ * using @djangocfg/ui components.
28
+ *
29
+ * @example
30
+ * ```tsx
31
+ * const schema = {
32
+ * type: 'object',
33
+ * required: ['name'],
34
+ * properties: {
35
+ * name: { type: 'string', title: 'Name' },
36
+ * age: { type: 'number', title: 'Age' },
37
+ * active: { type: 'boolean', title: 'Active' }
38
+ * }
39
+ * };
40
+ *
41
+ * <JsonSchemaForm
42
+ * schema={schema}
43
+ * onSubmit={(data) => console.log(data.formData)}
44
+ * />
45
+ * ```
46
+ */
47
+ export function JsonSchemaForm<T = any>(props: JsonSchemaFormProps<T>) {
48
+ const {
49
+ schema,
50
+ uiSchema,
51
+ formData,
52
+ onSubmit,
53
+ onChange,
54
+ onError,
55
+ showErrorList = 'top',
56
+ liveValidate = false,
57
+ disabled = false,
58
+ readonly = false,
59
+ className,
60
+ showSubmitButton = true,
61
+ submitButtonText = 'Submit',
62
+ ...restProps
63
+ } = props;
64
+
65
+ // Validate and normalize schema before render
66
+ const validatedSchema = useMemo(() => {
67
+ if (process.env.NODE_ENV === 'development') {
68
+ consola.info('[JsonSchemaForm] Validating schema...', schema);
69
+ }
70
+ const result = validateSchema(schema);
71
+ if (!result && process.env.NODE_ENV === 'development') {
72
+ consola.error('[JsonSchemaForm] Schema validation failed');
73
+ }
74
+ return result;
75
+ }, [schema]);
76
+
77
+ // Normalize form data before render
78
+ const normalizedFormData = useMemo(() => {
79
+ if (!validatedSchema) {
80
+ if (process.env.NODE_ENV === 'development') {
81
+ consola.warn('[JsonSchemaForm] Cannot normalize formData - invalid schema');
82
+ }
83
+ return null;
84
+ }
85
+ if (process.env.NODE_ENV === 'development') {
86
+ consola.info('[JsonSchemaForm] Normalizing formData...', formData);
87
+ }
88
+ const normalized = normalizeFormData<T>(formData, validatedSchema);
89
+ if (process.env.NODE_ENV === 'development') {
90
+ consola.info('[JsonSchemaForm] Normalized formData:', normalized);
91
+ }
92
+ return normalized;
93
+ }, [formData, validatedSchema]);
94
+
95
+ // Memoize widgets mapping to prevent recreation on every render
96
+ // IMPORTANT: Widget keys must match RJSF's expected names:
97
+ // - For type: string -> uses 'TextWidget' or 'text'
98
+ // - For type: number/integer -> uses 'updown' or 'range'
99
+ // - For type: boolean -> uses 'checkbox' or 'select'
100
+ // - For enum fields -> uses 'SelectWidget' or 'select'
101
+ const widgets: RegistryWidgetsType = useMemo(() => ({
102
+ // Standard widget names (PascalCase) - used by RJSF internally
103
+ TextWidget,
104
+ NumberWidget,
105
+ CheckboxWidget,
106
+ SelectWidget,
107
+ SwitchWidget,
108
+ ColorWidget,
109
+ SliderWidget,
110
+ // Lowercase aliases - for uiSchema 'ui:widget' references
111
+ text: TextWidget,
112
+ number: NumberWidget,
113
+ checkbox: CheckboxWidget,
114
+ select: SelectWidget,
115
+ switch: SwitchWidget,
116
+ color: ColorWidget,
117
+ slider: SliderWidget,
118
+ range: SliderWidget, // alias
119
+ }), []);
120
+
121
+ // Memoize templates to prevent recreation on every render
122
+ const templates = useMemo(() => ({
123
+ FieldTemplate,
124
+ ObjectFieldTemplate,
125
+ ArrayFieldTemplate,
126
+ ArrayFieldItemTemplate,
127
+ ErrorListTemplate,
128
+ BaseInputTemplate,
129
+ }), []);
130
+
131
+ // Memoize callbacks
132
+ const handleSubmit = useCallback((data: any) => {
133
+ if (onSubmit) {
134
+ // Ensure clean data on submit
135
+ const cleanData = {
136
+ ...data,
137
+ formData: normalizeFormData(data.formData, validatedSchema!),
138
+ };
139
+ onSubmit(cleanData);
140
+ }
141
+ }, [onSubmit, validatedSchema]);
142
+
143
+ const handleChange = useCallback((data: any) => {
144
+ if (onChange) {
145
+ onChange(data);
146
+ }
147
+ }, [onChange]);
148
+
149
+ const handleError = useCallback((errors: any) => {
150
+ if (onError) {
151
+ onError(errors);
152
+ }
153
+ }, [onError]);
154
+
155
+ // Early return if schema is invalid
156
+ if (!validatedSchema) {
157
+ return (
158
+ <div className={className}>
159
+ <Alert variant="destructive">
160
+ <AlertCircle className="h-4 w-4" />
161
+ <AlertDescription>
162
+ Invalid schema provided. Please check the schema format.
163
+ </AlertDescription>
164
+ </Alert>
165
+ </div>
166
+ );
167
+ }
168
+
169
+ return (
170
+ <div className={className}>
171
+ <Form
172
+ schema={validatedSchema}
173
+ uiSchema={uiSchema}
174
+ formData={normalizedFormData}
175
+ validator={validator}
176
+ widgets={widgets}
177
+ templates={templates}
178
+ onSubmit={handleSubmit}
179
+ onChange={handleChange}
180
+ onError={handleError}
181
+ showErrorList={showErrorList}
182
+ liveValidate={liveValidate}
183
+ disabled={disabled}
184
+ readonly={readonly}
185
+ {...restProps}
186
+ >
187
+ {showSubmitButton && (
188
+ <div className="mt-6 flex gap-2">
189
+ <Button type="submit" disabled={disabled}>
190
+ {submitButtonText}
191
+ </Button>
192
+ </div>
193
+ )}
194
+ </Form>
195
+ </div>
196
+ );
197
+ }
@@ -0,0 +1,249 @@
1
+ 'use client';
2
+
3
+ import consola from 'consola';
4
+ import React, { useState } from 'react';
5
+
6
+ import {
7
+ Card, CardContent, CardDescription, CardHeader, CardTitle
8
+ } from '@djangocfg/ui-core/components';
9
+ import { RJSFSchema, UiSchema } from '@rjsf/utils';
10
+
11
+ import { JsonSchemaForm } from '../JsonSchemaForm';
12
+
13
+ /**
14
+ * Example JSON Schema for Bot Configuration
15
+ */
16
+ const botConfigSchema: RJSFSchema = {
17
+ $schema: 'http://json-schema.org/draft-07/schema#',
18
+ title: 'Bot Configuration',
19
+ type: 'object',
20
+ required: ['name', 'exchange', 'bot_type'],
21
+ properties: {
22
+ name: {
23
+ type: 'string',
24
+ title: 'Bot Name',
25
+ description: 'A unique name for your trading bot',
26
+ minLength: 3,
27
+ maxLength: 50,
28
+ },
29
+ active: {
30
+ type: 'boolean',
31
+ title: 'Active',
32
+ description: 'Enable or disable the bot',
33
+ default: true,
34
+ },
35
+ enabled: {
36
+ type: 'boolean',
37
+ title: 'Enabled',
38
+ description: 'Whether the bot is enabled for trading',
39
+ default: false,
40
+ },
41
+ exchange: {
42
+ type: 'string',
43
+ title: 'Exchange',
44
+ description: 'Select the trading exchange',
45
+ enum: ['binance', 'bybit', 'okx', 'kucoin'],
46
+ },
47
+ bot_type: {
48
+ type: 'string',
49
+ title: 'Bot Type',
50
+ description: 'Type of trading bot',
51
+ enum: ['spot', 'futures', 'margin'],
52
+ },
53
+ settings: {
54
+ type: 'object',
55
+ title: 'Bot Settings',
56
+ properties: {
57
+ max_trades: {
58
+ type: 'integer',
59
+ title: 'Maximum Trades',
60
+ description: 'Maximum number of concurrent trades',
61
+ minimum: 1,
62
+ maximum: 100,
63
+ default: 3,
64
+ },
65
+ trade_amount: {
66
+ type: 'number',
67
+ title: 'Trade Amount (USD)',
68
+ description: 'Amount to invest per trade',
69
+ minimum: 10,
70
+ maximum: 10000,
71
+ default: 100,
72
+ },
73
+ stop_loss: {
74
+ type: 'number',
75
+ title: 'Stop Loss (%)',
76
+ description: 'Stop loss percentage',
77
+ minimum: 0.1,
78
+ maximum: 50,
79
+ default: 5,
80
+ },
81
+ take_profit: {
82
+ type: 'number',
83
+ title: 'Take Profit (%)',
84
+ description: 'Take profit percentage',
85
+ minimum: 0.1,
86
+ maximum: 100,
87
+ default: 10,
88
+ },
89
+ strategy: {
90
+ type: 'string',
91
+ title: 'Trading Strategy',
92
+ enum: ['scalping', 'swing', 'arbitrage', 'grid'],
93
+ },
94
+ },
95
+ },
96
+ api_credentials: {
97
+ type: 'object',
98
+ title: 'API Credentials',
99
+ required: ['api_key', 'api_secret'],
100
+ properties: {
101
+ api_key: {
102
+ type: 'string',
103
+ title: 'API Key',
104
+ description: 'Your exchange API key',
105
+ },
106
+ api_secret: {
107
+ type: 'string',
108
+ title: 'API Secret',
109
+ description: 'Your exchange API secret',
110
+ },
111
+ testnet: {
112
+ type: 'boolean',
113
+ title: 'Use Testnet',
114
+ description: 'Use testnet environment for testing',
115
+ default: true,
116
+ },
117
+ },
118
+ },
119
+ notifications: {
120
+ type: 'object',
121
+ title: 'Notifications',
122
+ properties: {
123
+ email: {
124
+ type: 'boolean',
125
+ title: 'Email Notifications',
126
+ default: true,
127
+ },
128
+ telegram: {
129
+ type: 'boolean',
130
+ title: 'Telegram Notifications',
131
+ default: false,
132
+ },
133
+ webhook: {
134
+ type: 'string',
135
+ title: 'Webhook URL',
136
+ format: 'uri',
137
+ },
138
+ },
139
+ },
140
+ },
141
+ };
142
+
143
+ /**
144
+ * UI Schema for customizing form appearance
145
+ */
146
+ const uiSchema: UiSchema = {
147
+ 'ui:submitButtonOptions': {
148
+ submitText: 'Save Bot Configuration',
149
+ },
150
+ name: {
151
+ 'ui:placeholder': 'My Trading Bot',
152
+ },
153
+ active: {
154
+ 'ui:widget': 'SwitchWidget',
155
+ },
156
+ enabled: {
157
+ 'ui:widget': 'SwitchWidget',
158
+ },
159
+ exchange: {
160
+ 'ui:placeholder': 'Select exchange...',
161
+ },
162
+ bot_type: {
163
+ 'ui:placeholder': 'Select bot type...',
164
+ },
165
+ settings: {
166
+ 'ui:className': 'grid grid-cols-2 gap-4',
167
+ strategy: {
168
+ 'ui:placeholder': 'Select strategy...',
169
+ },
170
+ },
171
+ api_credentials: {
172
+ api_secret: {
173
+ 'ui:widget': 'password',
174
+ },
175
+ testnet: {
176
+ 'ui:widget': 'SwitchWidget',
177
+ },
178
+ },
179
+ notifications: {
180
+ email: {
181
+ 'ui:widget': 'SwitchWidget',
182
+ },
183
+ telegram: {
184
+ 'ui:widget': 'SwitchWidget',
185
+ },
186
+ webhook: {
187
+ 'ui:placeholder': 'https://example.com/webhook',
188
+ },
189
+ },
190
+ };
191
+
192
+ /**
193
+ * Example component demonstrating JsonSchemaForm usage
194
+ */
195
+ export function BotConfigExample() {
196
+ const [formData, setFormData] = useState<any>();
197
+ const [submittedData, setSubmittedData] = useState<any>(null);
198
+
199
+ const handleSubmit = (data: any) => {
200
+ consola.success('Form submitted:', data.formData);
201
+ setSubmittedData(data.formData);
202
+ };
203
+
204
+ const handleChange = (data: any) => {
205
+ setFormData(data.formData);
206
+ };
207
+
208
+ return (
209
+ <div className="container mx-auto p-6 max-w-4xl">
210
+ <div className="space-y-6">
211
+ <Card>
212
+ <CardHeader>
213
+ <CardTitle>Bot Configuration Form</CardTitle>
214
+ <CardDescription>
215
+ Example of JSON Schema Form with Bot Configuration
216
+ </CardDescription>
217
+ </CardHeader>
218
+ <CardContent>
219
+ <JsonSchemaForm
220
+ schema={botConfigSchema}
221
+ uiSchema={uiSchema}
222
+ formData={formData}
223
+ onSubmit={handleSubmit}
224
+ onChange={handleChange}
225
+ liveValidate={false}
226
+ showErrorList="top"
227
+ />
228
+ </CardContent>
229
+ </Card>
230
+
231
+ {submittedData && (
232
+ <Card>
233
+ <CardHeader>
234
+ <CardTitle>Submitted Data</CardTitle>
235
+ <CardDescription>
236
+ The data that was submitted from the form
237
+ </CardDescription>
238
+ </CardHeader>
239
+ <CardContent>
240
+ <pre className="p-4 bg-muted rounded-md overflow-auto text-sm">
241
+ {JSON.stringify(submittedData, null, 2)}
242
+ </pre>
243
+ </CardContent>
244
+ </Card>
245
+ )}
246
+ </div>
247
+ </div>
248
+ );
249
+ }
@@ -0,0 +1,161 @@
1
+ 'use client';
2
+
3
+ import consola from 'consola';
4
+ import React, { useState } from 'react';
5
+
6
+ import {
7
+ Card, CardContent, CardDescription, CardHeader, CardTitle
8
+ } from '@djangocfg/ui-core/components';
9
+ import { RJSFSchema } from '@rjsf/utils';
10
+
11
+ import { JsonSchemaForm } from '../JsonSchemaForm';
12
+
13
+ /**
14
+ * Real Bot Config Schema from API
15
+ * This is the actual schema returned by the backend
16
+ */
17
+ const realBotConfigSchema: RJSFSchema = {
18
+ type: 'object',
19
+ title: 'BotConfig',
20
+ $schema: 'http://json-schema.org/draft-07/schema#',
21
+ required: ['name', 'exchange'],
22
+ properties: {
23
+ name: {
24
+ type: 'string',
25
+ description: 'Bot name',
26
+ },
27
+ active: {
28
+ type: 'boolean',
29
+ description: 'Bot active',
30
+ },
31
+ enabled: {
32
+ type: 'boolean',
33
+ description: 'Bot enabled',
34
+ },
35
+ exchange: {
36
+ type: 'string',
37
+ description: 'Exchange name (binance, bybit, etc)',
38
+ },
39
+ direction: {
40
+ type: 'string',
41
+ description: 'Trading direction (long, short, both)',
42
+ },
43
+ amount_usdt: {
44
+ type: 'number',
45
+ description: 'Amount in USDT',
46
+ },
47
+ market_type: {
48
+ type: 'string',
49
+ description: 'Market type (spot, futures, swap)',
50
+ },
51
+ signal_type: {
52
+ type: 'string',
53
+ description: 'Signal type (listing, technical, etc)',
54
+ },
55
+ allowed_quotes: {
56
+ type: 'array',
57
+ items: {
58
+ type: 'string',
59
+ },
60
+ description: 'Allowed quote currencies',
61
+ },
62
+ allowed_sources: {
63
+ type: 'array',
64
+ items: {
65
+ type: 'string',
66
+ },
67
+ description: 'Allowed signal sources',
68
+ },
69
+ force_market_close_timer: {
70
+ type: 'integer',
71
+ description: 'Force close timer in seconds',
72
+ },
73
+ force_market_close_enabled: {
74
+ type: 'boolean',
75
+ description: 'Enable forced market close',
76
+ },
77
+ },
78
+ };
79
+
80
+ /**
81
+ * Real settings data from bot
82
+ */
83
+ const realSettings = {
84
+ version: '1.0.0',
85
+ hostname: 'botserver',
86
+ supported_exchanges: ['binance'],
87
+ supported_strategies: ['default'],
88
+ };
89
+
90
+ /**
91
+ * Example component with real bot config schema
92
+ */
93
+ export function RealBotConfigExample() {
94
+ const [formData, setFormData] = useState<any>(realSettings);
95
+ const [submittedData, setSubmittedData] = useState<any>(null);
96
+
97
+ const handleSubmit = (data: any) => {
98
+ consola.success('Form submitted:', data.formData);
99
+ setSubmittedData(data.formData);
100
+ };
101
+
102
+ const handleChange = (data: any) => {
103
+ consola.info('Form changed:', data.formData);
104
+ setFormData(data.formData);
105
+ };
106
+
107
+ return (
108
+ <div className="container mx-auto p-6 max-w-4xl">
109
+ <div className="space-y-6">
110
+ <Card>
111
+ <CardHeader>
112
+ <CardTitle>Real Bot Configuration Form</CardTitle>
113
+ <CardDescription>
114
+ Using actual schema from API response
115
+ </CardDescription>
116
+ </CardHeader>
117
+ <CardContent>
118
+ <JsonSchemaForm
119
+ schema={realBotConfigSchema}
120
+ formData={formData}
121
+ onSubmit={handleSubmit}
122
+ onChange={handleChange}
123
+ liveValidate={false}
124
+ showErrorList="top"
125
+ />
126
+ </CardContent>
127
+ </Card>
128
+
129
+ {submittedData && (
130
+ <Card>
131
+ <CardHeader>
132
+ <CardTitle>Submitted Data</CardTitle>
133
+ <CardDescription>
134
+ The data that was submitted from the form
135
+ </CardDescription>
136
+ </CardHeader>
137
+ <CardContent>
138
+ <pre className="p-4 bg-muted rounded-md overflow-auto text-sm">
139
+ {JSON.stringify(submittedData, null, 2)}
140
+ </pre>
141
+ </CardContent>
142
+ </Card>
143
+ )}
144
+
145
+ <Card>
146
+ <CardHeader>
147
+ <CardTitle>Current Form Data</CardTitle>
148
+ <CardDescription>
149
+ Real-time form data (onChange)
150
+ </CardDescription>
151
+ </CardHeader>
152
+ <CardContent>
153
+ <pre className="p-4 bg-muted rounded-md overflow-auto text-sm">
154
+ {JSON.stringify(formData, null, 2)}
155
+ </pre>
156
+ </CardContent>
157
+ </Card>
158
+ </div>
159
+ </div>
160
+ );
161
+ }
@@ -0,0 +1,46 @@
1
+ "use client"
2
+
3
+ /**
4
+ * JSON Schema Form Module
5
+ *
6
+ * A complete solution for generating forms from JSON Schema 7
7
+ * Built with React JSON Schema Form (rjsf), Radix UI, and Tailwind CSS
8
+ *
9
+ * Features:
10
+ * - Automatic form generation from JSON Schema
11
+ * - Custom widgets using @djangocfg/ui components
12
+ * - Validation with ajv8
13
+ * - TypeScript support
14
+ * - Responsive design
15
+ * - Dark mode support
16
+ *
17
+ * @example
18
+ * ```tsx
19
+ * import { JsonSchemaForm } from '@/components/JsonForm';
20
+ *
21
+ * const schema = {
22
+ * type: 'object',
23
+ * properties: {
24
+ * name: { type: 'string' },
25
+ * age: { type: 'number' }
26
+ * }
27
+ * };
28
+ *
29
+ * <JsonSchemaForm
30
+ * schema={schema}
31
+ * onSubmit={(data) => console.log(data)}
32
+ * />
33
+ * ```
34
+ */
35
+
36
+ export { JsonSchemaForm } from './JsonSchemaForm';
37
+ export type { JsonSchemaFormProps } from './types';
38
+
39
+ // Export widgets for custom usage
40
+ export * from './widgets';
41
+
42
+ // Export templates for custom usage
43
+ export * from './templates';
44
+
45
+ // Export utilities for advanced usage
46
+ export * from './utils';
@@ -0,0 +1,47 @@
1
+ "use client"
2
+
3
+ import React from 'react';
4
+
5
+ import { cn } from '@djangocfg/ui-core/lib';
6
+ import { ArrayFieldItemTemplateProps, getTemplate, getUiOptions } from '@rjsf/utils';
7
+
8
+ /**
9
+ * Array field item template for JSON Schema Form
10
+ * Renders individual array items with proper styling and action buttons
11
+ *
12
+ * In RJSF v6, this template is responsible for rendering each item in an array,
13
+ * including the item content (children) and the action buttons (remove, move up/down, copy).
14
+ */
15
+ export function ArrayFieldItemTemplate(props: ArrayFieldItemTemplateProps) {
16
+ const {
17
+ children,
18
+ className,
19
+ buttonsProps,
20
+ hasToolbar,
21
+ registry,
22
+ uiSchema,
23
+ } = props;
24
+
25
+ const uiOptions = getUiOptions(uiSchema);
26
+ const ArrayFieldItemButtonsTemplate = getTemplate(
27
+ 'ArrayFieldItemButtonsTemplate',
28
+ registry,
29
+ uiOptions,
30
+ );
31
+
32
+ return (
33
+ <div
34
+ className={cn(
35
+ 'flex gap-2 items-start p-4 rounded-md border bg-card',
36
+ className
37
+ )}
38
+ >
39
+ <div className="flex-1">{children}</div>
40
+ {hasToolbar && (
41
+ <div className="flex items-center gap-1">
42
+ <ArrayFieldItemButtonsTemplate {...buttonsProps} />
43
+ </div>
44
+ )}
45
+ </div>
46
+ );
47
+ }