@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
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @djangocfg/ui-nextjs
2
2
 
3
- Next.js UI library extending `@djangocfg/ui-core` with 70+ components built on Radix UI + Tailwind CSS v4.
3
+ Next.js UI library extending `@djangocfg/ui-core` with 69+ components built on Radix UI + Tailwind CSS v4.
4
4
 
5
5
  **Part of [DjangoCFG](https://djangocfg.com)** — modern Django framework for production-ready SaaS applications.
6
6
 
@@ -16,10 +16,10 @@ pnpm add @djangocfg/ui-nextjs
16
16
 
17
17
  ```
18
18
  @djangocfg/ui-nextjs
19
- ├── Re-exports everything from @djangocfg/ui-core (61 components, 10 hooks)
20
- ├── + Next.js specific components (10)
19
+ ├── Re-exports everything from @djangocfg/ui-core (60 components, 10 hooks)
20
+ ├── + Next.js specific components (9)
21
21
  ├── + Browser storage hooks (5)
22
- ├── + Blocks, Tools, Theme, Animations
22
+ ├── + Blocks, Theme, Animations
23
23
  ```
24
24
 
25
25
  | Package | Use Case |
@@ -29,10 +29,10 @@ pnpm add @djangocfg/ui-nextjs
29
29
 
30
30
  ## Components
31
31
 
32
- ### From ui-core (61)
32
+ ### From ui-core (60)
33
33
  All components from `@djangocfg/ui-core` are re-exported.
34
34
 
35
- ### Next.js Specific (10)
35
+ ### Next.js Specific (9)
36
36
 
37
37
  | Component | Why Next.js |
38
38
  |-----------|-------------|
@@ -45,7 +45,6 @@ All components from `@djangocfg/ui-core` are re-exported.
45
45
  | `Pagination` | Uses `next/link` |
46
46
  | `SSRPagination` | Uses `next/link` + server components |
47
47
  | `DownloadButton` | Uses `localStorage` for auth |
48
- | `SonnerToaster` | Sonner toast integration |
49
48
 
50
49
  ### MultiSelect Pro
51
50
  `MultiSelectPro` `MultiSelectProAsync` — Advanced multi-select with async loading
@@ -57,13 +56,6 @@ All components from `@djangocfg/ui-core` are re-exported.
57
56
  import { Hero } from '@djangocfg/ui-nextjs/blocks';
58
57
  ```
59
58
 
60
- ### Tools (7)
61
- `JsonTree` `PrettyCode` `Mermaid` `LottiePlayer` `AudioPlayer` `VideoPlayer` `ImageViewer`
62
-
63
- ```tsx
64
- import { PrettyCode, AudioPlayer, VideoPlayer } from '@djangocfg/ui-nextjs/tools';
65
- ```
66
-
67
59
  ## Hooks
68
60
 
69
61
  ### From ui-core (10)
@@ -135,7 +127,6 @@ mediaLog.buffer(buffered, duration);
135
127
  | `@djangocfg/ui-nextjs/components` | Components only |
136
128
  | `@djangocfg/ui-nextjs/hooks` | Hooks only |
137
129
  | `@djangocfg/ui-nextjs/blocks` | Landing page blocks |
138
- | `@djangocfg/ui-nextjs/tools` | JsonTree, Mermaid, Media players |
139
130
  | `@djangocfg/ui-nextjs/lib` | Logger, utilities |
140
131
  | `@djangocfg/ui-nextjs/theme` | ThemeProvider, ThemeToggle |
141
132
  | `@djangocfg/ui-nextjs/styles` | CSS |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@djangocfg/ui-nextjs",
3
- "version": "2.1.89",
3
+ "version": "2.1.91",
4
4
  "description": "Next.js UI component library with Radix UI primitives, Tailwind CSS styling, charts, and form components",
5
5
  "keywords": [
6
6
  "ui-components",
@@ -36,10 +36,7 @@
36
36
  ".": "./src/index.ts",
37
37
  "./components": "./src/components/index.ts",
38
38
  "./hooks": "./src/hooks/index.ts",
39
- "./layouts": "./src/layouts/index.ts",
40
39
  "./blocks": "./src/blocks/index.ts",
41
- "./lib": "./src/lib/index.ts",
42
- "./tools": "./src/tools/index.ts",
43
40
  "./animations": "./src/animations/index.ts",
44
41
  "./theme": "./src/theme/index.ts",
45
42
  "./types": "./src/types/index.ts",
@@ -58,8 +55,8 @@
58
55
  "check": "tsc --noEmit"
59
56
  },
60
57
  "peerDependencies": {
61
- "@djangocfg/api": "^2.1.89",
62
- "@djangocfg/ui-core": "^2.1.89",
58
+ "@djangocfg/api": "^2.1.91",
59
+ "@djangocfg/ui-core": "^2.1.91",
63
60
  "@types/react": "^19.1.0",
64
61
  "@types/react-dom": "^19.1.0",
65
62
  "consola": "^3.4.2",
@@ -74,16 +71,10 @@
74
71
  "zustand": "^5.0.9"
75
72
  },
76
73
  "dependencies": {
74
+ "@djangocfg/ui-tools": "^2.1.91",
77
75
  "@radix-ui/react-dropdown-menu": "^2.1.16",
78
76
  "@radix-ui/react-icons": "^1.3.2",
79
- "@radix-ui/react-menubar": "^1.1.16",
80
- "@radix-ui/react-navigation-menu": "^1.2.14",
81
77
  "@radix-ui/react-slot": "^1.2.4",
82
- "@rjsf/core": "^6.1.2",
83
- "@rjsf/utils": "^6.1.2",
84
- "@rjsf/validator-ajv8": "^6.1.2",
85
- "@vidstack/react": "next",
86
- "@wavesurfer/react": "^1.0.12",
87
78
  "@web3icons/react": "^4.0.26",
88
79
  "chart.js": "^4.5.0",
89
80
  "class-variance-authority": "^0.7.1",
@@ -91,26 +82,16 @@
91
82
  "cytoscape-cose-bilkent": "^4.1.0",
92
83
  "input-otp": "1.4.2",
93
84
  "libphonenumber-js": "^1.12.24",
94
- "media-icons": "next",
95
- "mermaid": "^11.12.0",
96
85
  "next-themes": "^0.4.6",
97
- "prism-react-renderer": "^2.4.1",
98
86
  "react-chartjs-2": "^5.3.0",
99
87
  "react-device-detect": "^2.2.3",
100
88
  "react-hotkeys-hook": "^5.2.1",
101
- "react-json-tree": "^0.20.0",
102
- "react-lottie-player": "^2.1.0",
103
- "react-markdown": "10.1.0",
104
89
  "react-sticky-box": "^2.0.5",
105
- "react-zoom-pan-pinch": "^3.7.0",
106
90
  "recharts": "2.15.4",
107
- "remark-gfm": "4.0.1",
108
- "sonner": "2.0.7",
109
- "vidstack": "next",
110
- "wavesurfer.js": "^7.12.1"
91
+ "sonner": "2.0.7"
111
92
  },
112
93
  "devDependencies": {
113
- "@djangocfg/typescript-config": "^2.1.89",
94
+ "@djangocfg/typescript-config": "^2.1.91",
114
95
  "@types/node": "^24.7.2",
115
96
  "eslint": "^9.37.0",
116
97
  "tailwindcss-animate": "1.0.7",
@@ -3,7 +3,7 @@
3
3
  import React from 'react';
4
4
  import Image from 'next/image';
5
5
  import { cn } from '@djangocfg/ui-core/lib';
6
- import { VideoPlayer } from '../../tools/VideoPlayer';
6
+ import { VideoPlayer } from '@djangocfg/ui-tools';
7
7
  import type { SplitHeroMedia as SplitHeroMediaType } from './types';
8
8
 
9
9
  interface SplitHeroMediaProps {
@@ -8,11 +8,9 @@ export * from '@djangocfg/ui-core/components';
8
8
  // ============================================================================
9
9
 
10
10
  // Navigation Components (Next.js)
11
- export { NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, navigationMenuTriggerStyle } from './navigation-menu';
12
11
  export { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, BreadcrumbEllipsis } from './breadcrumb';
13
12
  export { BreadcrumbNavigation } from './breadcrumb-navigation';
14
13
  export type { BreadcrumbItem as BreadcrumbNavigationItem, BreadcrumbNavigationProps } from './breadcrumb-navigation';
15
- export { Menubar, MenubarContent, MenubarItem, MenubarMenu, MenubarSeparator, MenubarShortcut, MenubarTrigger } from './menubar';
16
14
 
17
15
  // Interactive Components (Next.js)
18
16
  export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from './dropdown-menu';
@@ -23,9 +21,6 @@ export { SSRPagination } from './ssr-pagination';
23
21
  export { StaticPagination, useDRFPaginationInfo, useDRFPagination } from './pagination-static';
24
22
  export type { DRFPaginatedResponse } from './pagination-static';
25
23
 
26
- // Phone Input (uses DropdownMenu)
27
- export { PhoneInput } from './phone-input';
28
-
29
24
  // Sidebar (Next.js)
30
25
  export {
31
26
  Sidebar,
@@ -53,38 +48,3 @@ export {
53
48
  SidebarTrigger,
54
49
  useSidebar,
55
50
  } from './sidebar';
56
-
57
- // Download Button (uses localStorage for auth token)
58
- export { DownloadButton } from './button-download';
59
- export type { DownloadButtonProps } from './button-download';
60
-
61
- // Sonner Toast (Next.js specific)
62
- export { Toaster as SonnerToaster } from './sonner';
63
-
64
- // MultiSelect Pro (advanced component)
65
- export { MultiSelectPro } from './multi-select-pro';
66
- export type {
67
- MultiSelectProOption,
68
- MultiSelectProProps,
69
- MultiSelectProGroup,
70
- MultiSelectProRef,
71
- AnimationConfig,
72
- ResponsiveConfig
73
- } from './multi-select-pro';
74
- export { MultiSelectProAsync } from './multi-select-pro/async';
75
- export type {
76
- MultiSelectProAsyncOption,
77
- MultiSelectProAsyncProps,
78
- MultiSelectProAsyncGroup,
79
- MultiSelectProAsyncRef,
80
- } from './multi-select-pro/async';
81
- export { createOption, createOptions } from './multi-select-pro/helpers';
82
- export type { OptionBuilderConfig } from './multi-select-pro/helpers';
83
-
84
- // Markdown Components
85
- export { MarkdownMessage } from './markdown';
86
- export type { MarkdownMessageProps } from './markdown';
87
-
88
- // OTP Components (Smart OTP input with validation)
89
- export { OTPInput, InputOTPGroup, InputOTPSlot, InputOTPSeparator, useSmartOTP } from './otp';
90
- export type { OTPInputProps, OTPValidationMode, OTPPasteBehavior, OTPValidator } from './otp';
@@ -7,12 +7,6 @@ export * from '@djangocfg/ui-core/hooks';
7
7
  // Next.js/Browser specific hooks
8
8
  // ============================================================================
9
9
 
10
- // Storage hooks (browser localStorage/sessionStorage)
11
- export { useLocalStorage } from './useLocalStorage';
12
- export type { UseLocalStorageOptions } from './useLocalStorage';
13
- export { useSessionStorage } from './useSessionStorage';
14
- export type { UseSessionStorageOptions } from './useSessionStorage';
15
-
16
10
  // Theme hook (standalone, no provider required)
17
11
  export { useResolvedTheme } from './useResolvedTheme';
18
12
  export type { ResolvedTheme } from './useResolvedTheme';
package/src/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  // ============================================================================
2
- // @djangocfg/ui - Main Export File
2
+ // @djangocfg/ui-nextjs - Main Export File
3
3
  // ============================================================================
4
4
 
5
5
  // Re-export everything from components
@@ -14,14 +14,5 @@ export * from './blocks';
14
14
  // Re-export animations
15
15
  export * from './animations';
16
16
 
17
- // Re-export lib utilities
18
- export * from './lib';
19
-
20
- // Re-export tools
21
- export * from './tools';
22
-
23
17
  // Re-export theme
24
- export * from './theme';
25
-
26
- // Re-export stores
27
- export * from './stores';
18
+ export * from './theme';
@@ -1,277 +0,0 @@
1
- "use client"
2
-
3
- import { AlertCircle, CheckCircle2, Download, Loader2 } from 'lucide-react';
4
- import * as React from 'react';
5
-
6
- import { Button, ButtonProps} from '@djangocfg/ui-core/components';
7
- import { cn } from '@djangocfg/ui-core/lib';
8
-
9
- import { useLocalStorage } from '../hooks/useLocalStorage';
10
-
11
- // Token key used by the API client
12
- const TOKEN_KEY = "auth_token"
13
-
14
- export interface DownloadButtonProps extends Omit<ButtonProps, 'onClick'> {
15
- /**
16
- * URL to download from
17
- */
18
- url: string
19
-
20
- /**
21
- * Optional filename override. If not provided, will try to extract from Content-Disposition header
22
- */
23
- filename?: string
24
-
25
- /**
26
- * Optional callback when download starts
27
- */
28
- onDownloadStart?: () => void
29
-
30
- /**
31
- * Optional callback when download completes
32
- */
33
- onDownloadComplete?: (filename: string) => void
34
-
35
- /**
36
- * Optional callback when download fails
37
- */
38
- onDownloadError?: (error: Error) => void
39
-
40
- /**
41
- * Use fetch API for download (allows progress tracking and auth headers)
42
- * Default: true
43
- */
44
- useFetch?: boolean
45
-
46
- /**
47
- * Show download status icons (loading, success, error)
48
- * Default: true
49
- */
50
- showStatus?: boolean
51
-
52
- /**
53
- * Auto-reset status after success/error (in ms)
54
- * Default: 2000
55
- */
56
- statusResetDelay?: number
57
-
58
- /**
59
- * Method for download (GET or POST)
60
- * Default: GET
61
- */
62
- method?: 'GET' | 'POST'
63
-
64
- /**
65
- * Optional request body for POST requests
66
- */
67
- body?: any
68
- }
69
-
70
- type DownloadStatus = 'idle' | 'downloading' | 'success' | 'error'
71
-
72
- const DownloadButton = React.forwardRef<HTMLButtonElement, DownloadButtonProps>(
73
- (
74
- {
75
- url,
76
- filename,
77
- onDownloadStart,
78
- onDownloadComplete,
79
- onDownloadError,
80
- useFetch = true,
81
- showStatus = true,
82
- statusResetDelay = 2000,
83
- method = 'GET',
84
- body,
85
- children,
86
- disabled,
87
- className,
88
- ...props
89
- },
90
- ref
91
- ) => {
92
- const [status, setStatus] = React.useState<DownloadStatus>('idle')
93
- const resetTimeoutRef = React.useRef<NodeJS.Timeout | undefined>(undefined)
94
-
95
- // Get auth token from localStorage
96
- const [token] = useLocalStorage<string>(TOKEN_KEY, '')
97
-
98
- // Clean up timeout on unmount
99
- React.useEffect(() => {
100
- return () => {
101
- if (resetTimeoutRef.current) {
102
- clearTimeout(resetTimeoutRef.current)
103
- }
104
- }
105
- }, [])
106
-
107
- /**
108
- * Extract filename from Content-Disposition header
109
- */
110
- const extractFilename = (headers: Headers): string | null => {
111
- const disposition = headers.get('Content-Disposition')
112
- if (!disposition) return null
113
-
114
- // Try to match: filename*=UTF-8''example.txt or filename="example.txt"
115
- const filenameMatch = disposition.match(/filename\*?=(?:UTF-8'')?["']?([^"';]+)["']?/i)
116
- if (filenameMatch && filenameMatch[1]) {
117
- return decodeURIComponent(filenameMatch[1])
118
- }
119
-
120
- return null
121
- }
122
-
123
- /**
124
- * Trigger browser download for blob
125
- */
126
- const triggerDownload = (blob: Blob, downloadFilename: string) => {
127
- const url = window.URL.createObjectURL(blob)
128
- const a = document.createElement('a')
129
- a.href = url
130
- a.download = downloadFilename
131
- document.body.appendChild(a)
132
- a.click()
133
- document.body.removeChild(a)
134
- window.URL.revokeObjectURL(url)
135
- }
136
-
137
- /**
138
- * Reset status after delay
139
- */
140
- const scheduleStatusReset = () => {
141
- if (resetTimeoutRef.current) {
142
- clearTimeout(resetTimeoutRef.current)
143
- }
144
- resetTimeoutRef.current = setTimeout(() => {
145
- setStatus('idle')
146
- }, statusResetDelay)
147
- }
148
-
149
- /**
150
- * Download using fetch API (supports auth, progress, error handling)
151
- */
152
- const downloadWithFetch = async () => {
153
- try {
154
- setStatus('downloading')
155
- onDownloadStart?.()
156
-
157
- const headers: HeadersInit = {}
158
-
159
- // Add authorization header if token is available
160
- if (token) {
161
- headers['Authorization'] = `Bearer ${token}`
162
- }
163
-
164
- const options: RequestInit = {
165
- method,
166
- headers,
167
- }
168
-
169
- if (method === 'POST' && body) {
170
- options.body = JSON.stringify(body)
171
- options.headers = {
172
- ...options.headers,
173
- 'Content-Type': 'application/json',
174
- }
175
- }
176
-
177
- const response = await fetch(url, options)
178
-
179
- if (!response.ok) {
180
- throw new Error(`Download failed: ${response.status} ${response.statusText}`)
181
- }
182
-
183
- const blob = await response.blob()
184
-
185
- // Determine filename
186
- const downloadFilename =
187
- filename ||
188
- extractFilename(response.headers) ||
189
- `download-${Date.now()}.bin`
190
-
191
- // Trigger download
192
- triggerDownload(blob, downloadFilename)
193
-
194
- setStatus('success')
195
- onDownloadComplete?.(downloadFilename)
196
- scheduleStatusReset()
197
- } catch (error) {
198
- console.error('Download error:', error)
199
- setStatus('error')
200
- onDownloadError?.(error as Error)
201
- scheduleStatusReset()
202
- }
203
- }
204
-
205
- /**
206
- * Simple download using window.open (fallback)
207
- */
208
- const downloadWithWindowOpen = () => {
209
- try {
210
- setStatus('downloading')
211
- onDownloadStart?.()
212
- window.open(url, '_blank')
213
-
214
- // We can't really track success/failure with window.open
215
- // So just assume success after a short delay
216
- setTimeout(() => {
217
- setStatus('success')
218
- onDownloadComplete?.(filename || 'file')
219
- scheduleStatusReset()
220
- }, 500)
221
- } catch (error) {
222
- console.error('Download error:', error)
223
- setStatus('error')
224
- onDownloadError?.(error as Error)
225
- scheduleStatusReset()
226
- }
227
- }
228
-
229
- /**
230
- * Handle download click
231
- */
232
- const handleDownload = () => {
233
- if (status === 'downloading') return
234
-
235
- if (useFetch) {
236
- downloadWithFetch()
237
- } else {
238
- downloadWithWindowOpen()
239
- }
240
- }
241
-
242
- /**
243
- * Render status icon
244
- */
245
- const renderStatusIcon = () => {
246
- if (!showStatus) return null
247
-
248
- switch (status) {
249
- case 'downloading':
250
- return <Loader2 className="animate-spin" />
251
- case 'success':
252
- return <CheckCircle2 className="text-green-600" />
253
- case 'error':
254
- return <AlertCircle className="text-red-600" />
255
- default:
256
- return <Download />
257
- }
258
- }
259
-
260
- return (
261
- <Button
262
- ref={ref}
263
- onClick={handleDownload}
264
- disabled={disabled || status === 'downloading'}
265
- className={cn(className)}
266
- {...props}
267
- >
268
- {renderStatusIcon()}
269
- {children}
270
- </Button>
271
- )
272
- }
273
- )
274
-
275
- DownloadButton.displayName = "DownloadButton"
276
-
277
- export { DownloadButton }