@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.
- package/README.md +6 -15
- package/package.json +6 -25
- package/src/blocks/SplitHero/SplitHeroMedia.tsx +1 -1
- package/src/components/index.ts +0 -40
- package/src/hooks/index.ts +0 -6
- package/src/index.ts +2 -11
- package/src/components/button-download.tsx +0 -277
- package/src/components/markdown/MarkdownMessage.tsx +0 -340
- package/src/components/markdown/index.ts +0 -5
- package/src/components/menubar.tsx +0 -275
- package/src/components/multi-select-pro/async.tsx +0 -598
- package/src/components/multi-select-pro/helpers.tsx +0 -84
- package/src/components/multi-select-pro/index.tsx +0 -612
- package/src/components/navigation-menu.tsx +0 -154
- package/src/components/otp/index.tsx +0 -197
- package/src/components/otp/types.ts +0 -133
- package/src/components/otp/use-otp-input.ts +0 -225
- package/src/components/phone-input.tsx +0 -277
- package/src/components/sonner.tsx +0 -32
- package/src/hooks/useLocalStorage.ts +0 -300
- package/src/hooks/useSessionStorage.ts +0 -290
- package/src/lib/index.ts +0 -5
- package/src/lib/logger/index.ts +0 -10
- package/src/lib/logger/logStore.ts +0 -122
- package/src/lib/logger/logger.ts +0 -175
- package/src/lib/logger/types.ts +0 -82
- package/src/stores/index.ts +0 -8
- package/src/stores/mediaCache.ts +0 -534
- package/src/tools/AudioPlayer/README.md +0 -206
- package/src/tools/AudioPlayer/components/HybridAudioPlayer.tsx +0 -216
- package/src/tools/AudioPlayer/components/HybridSimplePlayer.tsx +0 -280
- package/src/tools/AudioPlayer/components/HybridWaveform.tsx +0 -279
- package/src/tools/AudioPlayer/components/ReactiveCover/AudioReactiveCover.tsx +0 -149
- package/src/tools/AudioPlayer/components/ReactiveCover/effects/GlowEffect.tsx +0 -110
- package/src/tools/AudioPlayer/components/ReactiveCover/effects/MeshEffect.tsx +0 -58
- package/src/tools/AudioPlayer/components/ReactiveCover/effects/OrbsEffect.tsx +0 -45
- package/src/tools/AudioPlayer/components/ReactiveCover/effects/SpotlightEffect.tsx +0 -82
- package/src/tools/AudioPlayer/components/ReactiveCover/effects/index.ts +0 -8
- package/src/tools/AudioPlayer/components/ReactiveCover/index.ts +0 -6
- package/src/tools/AudioPlayer/components/index.ts +0 -22
- package/src/tools/AudioPlayer/context/HybridAudioProvider.tsx +0 -158
- package/src/tools/AudioPlayer/context/index.ts +0 -16
- package/src/tools/AudioPlayer/effects/index.ts +0 -412
- package/src/tools/AudioPlayer/hooks/index.ts +0 -35
- package/src/tools/AudioPlayer/hooks/useHybridAudio.ts +0 -387
- package/src/tools/AudioPlayer/hooks/useHybridAudioAnalysis.ts +0 -95
- package/src/tools/AudioPlayer/hooks/useVisualization.tsx +0 -207
- package/src/tools/AudioPlayer/index.ts +0 -133
- package/src/tools/AudioPlayer/types/effects.ts +0 -73
- package/src/tools/AudioPlayer/types/index.ts +0 -27
- package/src/tools/AudioPlayer/utils/debug.ts +0 -14
- package/src/tools/AudioPlayer/utils/formatTime.ts +0 -10
- package/src/tools/AudioPlayer/utils/index.ts +0 -6
- package/src/tools/ImageViewer/@refactoring/00-PLAN.md +0 -71
- package/src/tools/ImageViewer/@refactoring/01-TYPES.md +0 -121
- package/src/tools/ImageViewer/@refactoring/02-UTILS.md +0 -143
- package/src/tools/ImageViewer/@refactoring/03-HOOKS.md +0 -261
- package/src/tools/ImageViewer/@refactoring/04-COMPONENTS.md +0 -427
- package/src/tools/ImageViewer/@refactoring/05-EXECUTION-CHECKLIST.md +0 -126
- package/src/tools/ImageViewer/README.md +0 -200
- package/src/tools/ImageViewer/components/ImageInfo.tsx +0 -44
- package/src/tools/ImageViewer/components/ImageToolbar.tsx +0 -150
- package/src/tools/ImageViewer/components/ImageViewer.tsx +0 -241
- package/src/tools/ImageViewer/components/index.ts +0 -7
- package/src/tools/ImageViewer/hooks/index.ts +0 -9
- package/src/tools/ImageViewer/hooks/useImageLoading.ts +0 -204
- package/src/tools/ImageViewer/hooks/useImageTransform.ts +0 -101
- package/src/tools/ImageViewer/index.ts +0 -60
- package/src/tools/ImageViewer/types.ts +0 -81
- package/src/tools/ImageViewer/utils/constants.ts +0 -59
- package/src/tools/ImageViewer/utils/debug.ts +0 -14
- package/src/tools/ImageViewer/utils/index.ts +0 -17
- package/src/tools/ImageViewer/utils/lqip.ts +0 -47
- package/src/tools/JsonForm/JsonSchemaForm.tsx +0 -197
- package/src/tools/JsonForm/examples/BotConfigExample.tsx +0 -249
- package/src/tools/JsonForm/examples/RealBotConfigExample.tsx +0 -161
- package/src/tools/JsonForm/index.ts +0 -46
- package/src/tools/JsonForm/templates/ArrayFieldItemTemplate.tsx +0 -47
- package/src/tools/JsonForm/templates/ArrayFieldTemplate.tsx +0 -74
- package/src/tools/JsonForm/templates/BaseInputTemplate.tsx +0 -107
- package/src/tools/JsonForm/templates/ErrorListTemplate.tsx +0 -35
- package/src/tools/JsonForm/templates/FieldTemplate.tsx +0 -62
- package/src/tools/JsonForm/templates/ObjectFieldTemplate.tsx +0 -116
- package/src/tools/JsonForm/templates/index.ts +0 -12
- package/src/tools/JsonForm/types.ts +0 -83
- package/src/tools/JsonForm/utils.ts +0 -213
- package/src/tools/JsonForm/widgets/CheckboxWidget.tsx +0 -37
- package/src/tools/JsonForm/widgets/ColorWidget.tsx +0 -219
- package/src/tools/JsonForm/widgets/NumberWidget.tsx +0 -89
- package/src/tools/JsonForm/widgets/SelectWidget.tsx +0 -97
- package/src/tools/JsonForm/widgets/SliderWidget.tsx +0 -148
- package/src/tools/JsonForm/widgets/SwitchWidget.tsx +0 -35
- package/src/tools/JsonForm/widgets/TextWidget.tsx +0 -96
- package/src/tools/JsonForm/widgets/index.ts +0 -14
- package/src/tools/JsonTree/index.tsx +0 -243
- package/src/tools/LottiePlayer/LottiePlayer.client.tsx +0 -213
- package/src/tools/LottiePlayer/index.tsx +0 -55
- package/src/tools/LottiePlayer/types.ts +0 -108
- package/src/tools/LottiePlayer/useLottie.ts +0 -164
- package/src/tools/Mermaid/Mermaid.client.tsx +0 -82
- package/src/tools/Mermaid/components/MermaidCodeViewer.tsx +0 -95
- package/src/tools/Mermaid/components/MermaidFullscreenModal.tsx +0 -103
- package/src/tools/Mermaid/hooks/index.ts +0 -4
- package/src/tools/Mermaid/hooks/useMermaidCleanup.ts +0 -73
- package/src/tools/Mermaid/hooks/useMermaidFullscreen.ts +0 -46
- package/src/tools/Mermaid/hooks/useMermaidRenderer.ts +0 -226
- package/src/tools/Mermaid/hooks/useMermaidValidation.ts +0 -29
- package/src/tools/Mermaid/index.tsx +0 -41
- package/src/tools/Mermaid/utils/mermaid-helpers.ts +0 -33
- package/src/tools/OpenapiViewer/components/EndpointInfo.tsx +0 -149
- package/src/tools/OpenapiViewer/components/EndpointsLibrary.tsx +0 -263
- package/src/tools/OpenapiViewer/components/PlaygroundLayout.tsx +0 -125
- package/src/tools/OpenapiViewer/components/PlaygroundStepper.tsx +0 -100
- package/src/tools/OpenapiViewer/components/RequestBuilder.tsx +0 -157
- package/src/tools/OpenapiViewer/components/RequestParametersForm.tsx +0 -253
- package/src/tools/OpenapiViewer/components/ResponseViewer.tsx +0 -173
- package/src/tools/OpenapiViewer/components/VersionSelector.tsx +0 -68
- package/src/tools/OpenapiViewer/components/index.ts +0 -14
- package/src/tools/OpenapiViewer/constants.ts +0 -39
- package/src/tools/OpenapiViewer/context/PlaygroundContext.tsx +0 -337
- package/src/tools/OpenapiViewer/hooks/index.ts +0 -8
- package/src/tools/OpenapiViewer/hooks/useMobile.ts +0 -10
- package/src/tools/OpenapiViewer/hooks/useOpenApiSchema.ts +0 -199
- package/src/tools/OpenapiViewer/index.tsx +0 -38
- package/src/tools/OpenapiViewer/types.ts +0 -151
- package/src/tools/OpenapiViewer/utils/apiKeyManager.ts +0 -149
- package/src/tools/OpenapiViewer/utils/formatters.ts +0 -71
- package/src/tools/OpenapiViewer/utils/index.ts +0 -9
- package/src/tools/OpenapiViewer/utils/versionManager.ts +0 -161
- package/src/tools/PrettyCode/PrettyCode.client.tsx +0 -208
- package/src/tools/PrettyCode/index.tsx +0 -45
- package/src/tools/VideoPlayer/@refactoring/00-PLAN.md +0 -91
- package/src/tools/VideoPlayer/@refactoring/01-TYPES.md +0 -284
- package/src/tools/VideoPlayer/@refactoring/02-UTILS.md +0 -141
- package/src/tools/VideoPlayer/@refactoring/03-HOOKS.md +0 -178
- package/src/tools/VideoPlayer/@refactoring/04-COMPONENTS.md +0 -95
- package/src/tools/VideoPlayer/@refactoring/05-EXECUTION-CHECKLIST.md +0 -139
- package/src/tools/VideoPlayer/README.md +0 -264
- package/src/tools/VideoPlayer/components/VideoControls.tsx +0 -138
- package/src/tools/VideoPlayer/components/VideoErrorFallback.tsx +0 -174
- package/src/tools/VideoPlayer/components/VideoPlayer.tsx +0 -201
- package/src/tools/VideoPlayer/components/index.ts +0 -14
- package/src/tools/VideoPlayer/context/VideoPlayerContext.tsx +0 -52
- package/src/tools/VideoPlayer/context/index.ts +0 -8
- package/src/tools/VideoPlayer/hooks/index.ts +0 -12
- package/src/tools/VideoPlayer/hooks/useVideoPlayerSettings.ts +0 -70
- package/src/tools/VideoPlayer/hooks/useVideoPositionCache.ts +0 -116
- package/src/tools/VideoPlayer/index.ts +0 -77
- package/src/tools/VideoPlayer/providers/NativeProvider.tsx +0 -284
- package/src/tools/VideoPlayer/providers/StreamProvider.tsx +0 -505
- package/src/tools/VideoPlayer/providers/VidstackProvider.tsx +0 -400
- package/src/tools/VideoPlayer/providers/index.ts +0 -8
- package/src/tools/VideoPlayer/types/index.ts +0 -38
- package/src/tools/VideoPlayer/types/player.ts +0 -116
- package/src/tools/VideoPlayer/types/provider.ts +0 -93
- package/src/tools/VideoPlayer/types/sources.ts +0 -97
- package/src/tools/VideoPlayer/utils/debug.ts +0 -14
- package/src/tools/VideoPlayer/utils/fileSource.ts +0 -78
- package/src/tools/VideoPlayer/utils/index.ts +0 -12
- package/src/tools/VideoPlayer/utils/resolvers.ts +0 -75
- 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
|
|
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 (
|
|
20
|
-
├── + Next.js specific components (
|
|
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,
|
|
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 (
|
|
32
|
+
### From ui-core (60)
|
|
33
33
|
All components from `@djangocfg/ui-core` are re-exported.
|
|
34
34
|
|
|
35
|
-
### Next.js Specific (
|
|
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.
|
|
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.
|
|
62
|
-
"@djangocfg/ui-core": "^2.1.
|
|
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
|
-
"
|
|
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.
|
|
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 '
|
|
6
|
+
import { VideoPlayer } from '@djangocfg/ui-tools';
|
|
7
7
|
import type { SplitHeroMedia as SplitHeroMediaType } from './types';
|
|
8
8
|
|
|
9
9
|
interface SplitHeroMediaProps {
|
package/src/components/index.ts
CHANGED
|
@@ -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';
|
package/src/hooks/index.ts
CHANGED
|
@@ -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 }
|