@djangocfg/ui-nextjs 2.1.90 → 2.1.92

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,96 +0,0 @@
1
- "use client"
2
-
3
- import React, { useCallback, useMemo } from 'react';
4
-
5
- import { Input } from '@djangocfg/ui-core/components';
6
- import { WidgetProps } from '@rjsf/utils';
7
-
8
- /**
9
- * Text input widget for JSON Schema Form
10
- * Handles string fields with optional textarea for multiline
11
- */
12
- export function TextWidget(props: WidgetProps) {
13
- const {
14
- id,
15
- placeholder,
16
- required,
17
- disabled,
18
- readonly,
19
- autofocus,
20
- value,
21
- onChange,
22
- onBlur,
23
- onFocus,
24
- options,
25
- schema,
26
- rawErrors,
27
- } = props;
28
-
29
- // Memoize widget configuration
30
- const config = useMemo(() => ({
31
- isTextarea: options?.widget === 'textarea',
32
- rows: options?.rows || 3,
33
- emptyValue: options?.emptyValue,
34
- }), [options]);
35
-
36
- // Ensure value is always a string
37
- const safeValue = useMemo(() => {
38
- if (value === null || value === undefined) return '';
39
- return String(value);
40
- }, [value]);
41
-
42
- const hasError = useMemo(() => {
43
- return rawErrors && rawErrors.length > 0;
44
- }, [rawErrors]);
45
-
46
- const handleChange = useCallback((event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
47
- const newValue = event.target.value;
48
- onChange(newValue === '' ? config.emptyValue : newValue);
49
- }, [onChange, config.emptyValue]);
50
-
51
- const handleBlur = useCallback((event: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => {
52
- onBlur(id, event.target.value);
53
- }, [id, onBlur]);
54
-
55
- const handleFocus = useCallback((event: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => {
56
- onFocus(id, event.target.value);
57
- }, [id, onFocus]);
58
-
59
- if (config.isTextarea) {
60
- return (
61
- <textarea
62
- id={id}
63
- className={`flex min-h-[80px] w-full rounded-md border ${
64
- hasError ? 'border-destructive' : 'border-input'
65
- } bg-transparent px-3 py-2 text-base shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm`}
66
- placeholder={placeholder}
67
- disabled={disabled || readonly}
68
- readOnly={readonly}
69
- autoFocus={autofocus}
70
- value={safeValue}
71
- required={required}
72
- onChange={handleChange}
73
- onBlur={handleBlur}
74
- onFocus={handleFocus}
75
- rows={config.rows}
76
- />
77
- );
78
- }
79
-
80
- return (
81
- <Input
82
- id={id}
83
- type="text"
84
- placeholder={placeholder}
85
- disabled={disabled}
86
- readOnly={readonly}
87
- autoFocus={autofocus}
88
- value={safeValue}
89
- required={required}
90
- onChange={handleChange}
91
- onBlur={handleBlur}
92
- onFocus={handleFocus}
93
- className={hasError ? 'border-destructive' : ''}
94
- />
95
- );
96
- }
@@ -1,14 +0,0 @@
1
- /**
2
- * Custom widgets for JSON Schema Form
3
- *
4
- * Each widget is a React component that renders a specific form input type
5
- * using components from @djangocfg/ui
6
- */
7
-
8
- export { TextWidget } from './TextWidget';
9
- export { NumberWidget } from './NumberWidget';
10
- export { CheckboxWidget } from './CheckboxWidget';
11
- export { SelectWidget } from './SelectWidget';
12
- export { SwitchWidget } from './SwitchWidget';
13
- export { ColorWidget } from './ColorWidget';
14
- export { SliderWidget } from './SliderWidget';
@@ -1,243 +0,0 @@
1
- 'use client';
2
-
3
- import { ChevronDown, ChevronUp, Download } from 'lucide-react';
4
- import React, { useState } from 'react';
5
- import { CommonExternalProps, JSONTree } from 'react-json-tree';
6
-
7
- import { Button, CopyButton } from '@djangocfg/ui-core/components';
8
-
9
- export type { Language } from 'prism-react-renderer';
10
-
11
- export interface JsonTreeConfig {
12
- /** Maximum depth to expand automatically (default: 2) */
13
- maxAutoExpandDepth?: number;
14
- /** Maximum items in array to auto-expand (default: 10) */
15
- maxAutoExpandArrayItems?: number;
16
- /** Maximum object keys to auto-expand (default: 5) */
17
- maxAutoExpandObjectKeys?: number;
18
- /** Maximum string length before truncation (default: 200) */
19
- maxStringLength?: number;
20
- /** Collection limit for performance (default: 50) */
21
- collectionLimit?: number;
22
- /** Whether to show collection info (array length, object keys count) */
23
- showCollectionInfo?: boolean;
24
- /** Whether to show expand/collapse all buttons */
25
- showExpandControls?: boolean;
26
- /** Whether to show copy/download buttons */
27
- showActionButtons?: boolean;
28
- /** Custom CSS classes for the container */
29
- className?: string;
30
- /** Whether to preserve object key order (default: true) */
31
- preserveKeyOrder?: boolean;
32
- }
33
-
34
- interface JsonTreeComponentProps {
35
- title?: string;
36
- data: unknown;
37
- config?: JsonTreeConfig;
38
- /** Override for react-json-tree props */
39
- jsonTreeProps?: Partial<CommonExternalProps>;
40
- }
41
-
42
- const JsonTreeComponent = ({ title, data, config = {}, jsonTreeProps = {} }: JsonTreeComponentProps) => {
43
- // State for expand/collapse all
44
- const [expandAll, setExpandAll] = useState<boolean | null>(null);
45
- const [renderKey, setRenderKey] = useState(0);
46
-
47
- // Default configuration
48
- const {
49
- maxAutoExpandDepth = 2,
50
- maxAutoExpandArrayItems = 10,
51
- maxAutoExpandObjectKeys = 5,
52
- maxStringLength = 200,
53
- collectionLimit = 50,
54
- showCollectionInfo = true,
55
- showExpandControls = true,
56
- showActionButtons = true,
57
- className = '',
58
- preserveKeyOrder = true,
59
- } = config;
60
-
61
- // JSON Tree theme optimized for dark theme
62
- const jsonTreeTheme = {
63
- scheme: 'djangocfg-dark',
64
- base00: 'transparent', // Background
65
- base01: '#1a1a1a', // Lighter background
66
- base02: '#2a2a2a', // Selection background
67
- base03: '#6b7280', // Comments, invisibles
68
- base04: '#9ca3af', // Dark foreground
69
- base05: '#e5e7eb', // Default foreground
70
- base06: '#f3f4f6', // Light foreground
71
- base07: '#ffffff', // Lightest foreground
72
- base08: '#ef4444', // Red - for null, undefined
73
- base09: '#f97316', // Orange - for numbers
74
- base0A: '#eab308', // Yellow - for strings
75
- base0B: '#22c55e', // Green - for booleans (true)
76
- base0C: '#06b6d4', // Cyan - for dates, regex
77
- base0D: '#3b82f6', // Blue - for keys
78
- base0E: '#a855f7', // Purple - for functions
79
- base0F: '#f43f5e', // Pink - for deprecations
80
- };
81
-
82
- // Smart expansion logic
83
- const shouldExpandNodeInitially = (keyPath: readonly (string | number)[], nodeData: unknown, level: number) => {
84
- // If user explicitly clicked "Expand All", expand everything
85
- if (expandAll === true) return true;
86
-
87
- // If user explicitly clicked "Collapse All", collapse everything
88
- if (expandAll === false) return false;
89
-
90
- // Default auto-expansion (expandAll === null)
91
- // Always expand up to maxAutoExpandDepth
92
- if (level <= maxAutoExpandDepth) return true;
93
-
94
- // For arrays, expand if they have less than maxAutoExpandArrayItems
95
- if (Array.isArray(nodeData) && nodeData.length <= maxAutoExpandArrayItems) return true;
96
-
97
- // For objects, expand if they have less than maxAutoExpandObjectKeys
98
- if (nodeData && typeof nodeData === 'object' && !Array.isArray(nodeData)) {
99
- const keys = Object.keys(nodeData);
100
- return keys.length <= maxAutoExpandObjectKeys;
101
- }
102
-
103
- return false;
104
- };
105
-
106
- // Collection info display
107
- const getItemString = showCollectionInfo
108
- ? (nodeType: string, nodeData: unknown) => {
109
- if (nodeType === 'Array') {
110
- const length = Array.isArray(nodeData) ? nodeData.length : 0;
111
- return length > 0 ? <span className="text-muted-foreground text-sm">({length} items)</span> : null;
112
- }
113
- if (nodeType === 'Object') {
114
- const keys = nodeData && typeof nodeData === 'object' ? Object.keys(nodeData) : [];
115
- return keys.length > 0 ? <span className="text-muted-foreground text-sm">({keys.length} keys)</span> : null;
116
- }
117
- return null;
118
- }
119
- : () => null;
120
-
121
- // Value processing for better display
122
- const postprocessValue = (value: unknown) => {
123
- // Truncate very long strings
124
- if (typeof value === 'string' && value.length > maxStringLength) {
125
- return value.substring(0, maxStringLength) + '... (truncated)';
126
- }
127
- return value;
128
- };
129
-
130
- // Custom node detection for special formatting
131
- const isCustomNode = (value: unknown) => {
132
- // Mark URLs as custom nodes for special styling
133
- if (typeof value === 'string' && (value.startsWith('http://') || value.startsWith('https://'))) {
134
- return true;
135
- }
136
- return false;
137
- };
138
-
139
- // JSON string for copy/download
140
- const jsonString = JSON.stringify(data, null, 2);
141
-
142
- // Action handlers
143
- const handleDownload = () => {
144
- const blob = new Blob([jsonString], { type: 'application/json' });
145
- const url = URL.createObjectURL(blob);
146
- const a = document.createElement('a');
147
- a.href = url;
148
- a.download = 'data.json';
149
- document.body.appendChild(a);
150
- a.click();
151
- document.body.removeChild(a);
152
- URL.revokeObjectURL(url);
153
- };
154
-
155
- return (
156
- <div className={`relative border border-border rounded-sm h-full overflow-hidden ${className}`}>
157
- {/* Header with title and controls */}
158
- {(title || showExpandControls || showActionButtons) && (
159
- <div className="p-4 border-b border-border bg-muted/50 rounded-t-sm">
160
- <div className="flex items-center justify-between">
161
- {title && (
162
- <h6 className="text-lg font-semibold text-foreground">{title}</h6>
163
- )}
164
-
165
- {(showExpandControls || showActionButtons) && (
166
- <div className="flex items-center space-x-2">
167
- {/* Expand/Collapse Controls */}
168
- {showExpandControls && (
169
- <Button
170
- variant={expandAll === true ? "default" : "outline"}
171
- size="sm"
172
- onClick={() => {
173
- const newState = expandAll === true ? false : true;
174
- setExpandAll(newState);
175
- setRenderKey(prev => prev + 1);
176
- }}
177
- className="h-8 px-2"
178
- >
179
- {expandAll === true ? (
180
- <>
181
- <ChevronUp className="h-3 w-3" />
182
- <span className="ml-1 text-xs">Collapse All</span>
183
- </>
184
- ) : (
185
- <>
186
- <ChevronDown className="h-3 w-3" />
187
- <span className="ml-1 text-xs">Expand All</span>
188
- </>
189
- )}
190
- </Button>
191
- )}
192
-
193
- {/* Action Buttons */}
194
- {showActionButtons && (
195
- <>
196
- <CopyButton
197
- value={jsonString}
198
- variant="outline"
199
- size="sm"
200
- className="h-8 px-2"
201
- iconClassName="h-3 w-3"
202
- >
203
- Copy
204
- </CopyButton>
205
- <Button
206
- variant="outline"
207
- size="sm"
208
- onClick={handleDownload}
209
- className="h-8 px-2"
210
- >
211
- <Download className="h-3 w-3" />
212
- <span className="ml-1 text-xs hidden sm:inline">Download</span>
213
- </Button>
214
- </>
215
- )}
216
- </div>
217
- )}
218
- </div>
219
- </div>
220
- )}
221
-
222
- {/* JSON Tree Content */}
223
- <div className="h-full overflow-auto p-4">
224
- <JSONTree
225
- key={renderKey} // Force re-render when expand/collapse state changes
226
- data={data}
227
- theme={jsonTreeTheme}
228
- invertTheme={false}
229
- hideRoot={true}
230
- shouldExpandNodeInitially={shouldExpandNodeInitially}
231
- getItemString={getItemString}
232
- postprocessValue={postprocessValue}
233
- isCustomNode={isCustomNode}
234
- collectionLimit={collectionLimit}
235
- sortObjectKeys={!preserveKeyOrder}
236
- {...jsonTreeProps}
237
- />
238
- </div>
239
- </div>
240
- );
241
- };
242
-
243
- export default JsonTreeComponent;
@@ -1,213 +0,0 @@
1
- /**
2
- * LottiePlayer Component
3
- *
4
- * Universal Lottie animation player component
5
- */
6
-
7
- 'use client';
8
-
9
- import React from 'react';
10
- import Lottie from 'react-lottie-player';
11
-
12
- import { LottiePlayerProps } from './types';
13
- import { useLottie } from './useLottie';
14
-
15
- // Size presets mapping
16
- const SIZE_PRESETS = {
17
- xs: { width: 64, height: 64 },
18
- sm: { width: 128, height: 128 },
19
- md: { width: 256, height: 256 },
20
- lg: { width: 384, height: 384 },
21
- xl: { width: 512, height: 512 },
22
- full: { width: '100%', height: '100%' },
23
- } as const;
24
-
25
- /**
26
- * LottiePlayer component for displaying Lottie animations
27
- *
28
- * Features:
29
- * - Loads animations from URLs or objects
30
- * - Size presets or custom dimensions
31
- * - Playback controls (speed, direction, loop)
32
- * - Loading and error states
33
- * - Event callbacks
34
- *
35
- * Usage:
36
- * ```tsx
37
- * // From URL with size preset
38
- * <LottiePlayer
39
- * src="https://example.com/animation.json"
40
- * size="md"
41
- * autoplay
42
- * loop
43
- * />
44
- *
45
- * // From object with custom size
46
- * <LottiePlayer
47
- * src={animationData}
48
- * width={300}
49
- * height={300}
50
- * speed={1.5}
51
- * controls
52
- * />
53
- *
54
- * // With callbacks
55
- * <LottiePlayer
56
- * src="https://example.com/animation.json"
57
- * onLoad={() => console.log('Animation loaded')}
58
- * onComplete={() => console.log('Animation completed')}
59
- * onError={(err) => console.error('Error:', err)}
60
- * />
61
- * ```
62
- */
63
- export function LottiePlayer({
64
- src,
65
- size = 'md',
66
- width,
67
- height,
68
- autoplay = true,
69
- loop = true,
70
- speed = 1,
71
- direction = 1,
72
- controls = false,
73
- background,
74
- className,
75
- showLoading = true,
76
- onComplete,
77
- onLoad,
78
- onError,
79
- }: LottiePlayerProps) {
80
- // Load animation data using our custom hook
81
- const { animationData, isLoading, error, retry } = useLottie({ src });
82
-
83
- // Notify parent about load state
84
- React.useEffect(() => {
85
- if (animationData && onLoad) {
86
- onLoad();
87
- }
88
- }, [animationData, onLoad]);
89
-
90
- // Notify parent about errors
91
- React.useEffect(() => {
92
- if (error && onError) {
93
- onError(error);
94
- }
95
- }, [error, onError]);
96
-
97
- // Determine dimensions
98
- const dimensions = React.useMemo(() => {
99
- // Custom dimensions override size preset
100
- if (width !== undefined || height !== undefined) {
101
- return {
102
- width: width ?? SIZE_PRESETS[size].width,
103
- height: height ?? SIZE_PRESETS[size].height,
104
- };
105
- }
106
-
107
- // Use size preset
108
- return SIZE_PRESETS[size];
109
- }, [size, width, height]);
110
-
111
- // Handle complete event
112
- const handleComplete = React.useCallback(() => {
113
- if (onComplete) {
114
- onComplete();
115
- }
116
- }, [onComplete]);
117
-
118
- // Loading state
119
- if (isLoading && showLoading) {
120
- return (
121
- <div
122
- className={`flex items-center justify-center ${className || ''}`}
123
- style={{
124
- width: dimensions.width,
125
- height: dimensions.height,
126
- background: background || 'transparent',
127
- }}
128
- >
129
- <div className="flex flex-col items-center gap-2">
130
- <div className="h-8 w-8 animate-spin rounded-full border-4 border-gray-300 border-t-gray-900" />
131
- <span className="text-sm text-gray-500">Loading animation...</span>
132
- </div>
133
- </div>
134
- );
135
- }
136
-
137
- // Error state
138
- if (error) {
139
- return (
140
- <div
141
- className={`flex items-center justify-center ${className || ''}`}
142
- style={{
143
- width: dimensions.width,
144
- height: dimensions.height,
145
- background: background || 'transparent',
146
- }}
147
- >
148
- <div className="flex flex-col items-center gap-2 p-4 text-center">
149
- <svg
150
- className="h-8 w-8 text-red-500"
151
- fill="none"
152
- stroke="currentColor"
153
- viewBox="0 0 24 24"
154
- >
155
- <path
156
- strokeLinecap="round"
157
- strokeLinejoin="round"
158
- strokeWidth={2}
159
- d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
160
- />
161
- </svg>
162
- <div className="text-sm text-red-600">{error.message}</div>
163
- <button
164
- onClick={retry}
165
- className="rounded bg-red-100 px-3 py-1 text-sm text-red-700 hover:bg-red-200"
166
- >
167
- Retry
168
- </button>
169
- </div>
170
- </div>
171
- );
172
- }
173
-
174
- // No animation data
175
- if (!animationData) {
176
- return null;
177
- }
178
-
179
- // Render the Lottie player
180
- return (
181
- <div
182
- className={className}
183
- style={{
184
- width: dimensions.width,
185
- height: dimensions.height,
186
- background: background || 'transparent',
187
- }}
188
- >
189
- <Lottie
190
- animationData={animationData}
191
- play={autoplay}
192
- loop={loop}
193
- speed={speed}
194
- direction={direction}
195
- style={{
196
- width: '100%',
197
- height: '100%',
198
- }}
199
- onComplete={handleComplete}
200
- rendererSettings={{
201
- preserveAspectRatio: 'xMidYMid meet',
202
- }}
203
- />
204
- {controls && (
205
- <div className="mt-2 flex items-center justify-center gap-2">
206
- <span className="text-xs text-gray-500">
207
- Speed: {speed}x | Direction: {direction === 1 ? 'Forward' : 'Reverse'}
208
- </span>
209
- </div>
210
- )}
211
- </div>
212
- );
213
- }
@@ -1,55 +0,0 @@
1
- /**
2
- * LottiePlayer - Dynamic Import Wrapper
3
- *
4
- * Lazy loads the LottiePlayer component for optimal bundle size
5
- */
6
-
7
- 'use client';
8
-
9
- import dynamic from 'next/dynamic';
10
- import React from 'react';
11
-
12
- import { LottiePlayerProps } from './types';
13
-
14
- // Dynamically import the LottiePlayer component to reduce initial bundle size
15
- const LottiePlayerClient = dynamic(
16
- () => import('./LottiePlayer.client').then((mod) => ({ default: mod.LottiePlayer })),
17
- {
18
- ssr: false,
19
- loading: () => (
20
- <div className="flex items-center justify-center p-8">
21
- <div className="flex flex-col items-center gap-2">
22
- <div className="h-8 w-8 animate-spin rounded-full border-4 border-gray-300 border-t-gray-900" />
23
- <span className="text-sm text-gray-500">Loading player...</span>
24
- </div>
25
- </div>
26
- ),
27
- }
28
- );
29
-
30
- /**
31
- * LottiePlayer component wrapper with dynamic import
32
- *
33
- * This component automatically handles code splitting and lazy loading
34
- * of the Lottie player to optimize bundle size.
35
- *
36
- * Usage:
37
- * ```tsx
38
- * import { LottiePlayer } from '@djangocfg/ui-nextjs/tools';
39
- *
40
- * <LottiePlayer
41
- * src="https://example.com/animation.json"
42
- * size="md"
43
- * autoplay
44
- * loop
45
- * />
46
- * ```
47
- */
48
- export function LottiePlayer(props: LottiePlayerProps) {
49
- return <LottiePlayerClient {...props} />;
50
- }
51
-
52
- // Re-export types for convenience
53
- export type { LottiePlayerProps, LottieSize, LottieSpeed, LottieDirection } from './types';
54
- export { useLottie } from './useLottie';
55
- export type { UseLottieOptions, UseLottieReturn } from './useLottie';