@djangocfg/layouts 1.4.27 → 1.4.29
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/package.json +8 -8
- package/src/auth/context/AuthContext.tsx +4 -1
- package/src/auth/hooks/index.ts +2 -0
- package/src/auth/hooks/useAuthForm.ts +2 -0
- package/src/auth/hooks/useAuthGuard.ts +2 -0
- package/src/auth/hooks/useAutoAuth.ts +16 -11
- package/src/auth/hooks/useLocalStorage.ts +2 -0
- package/src/auth/hooks/useProfileCache.ts +2 -0
- package/src/auth/hooks/useSessionStorage.ts +2 -0
- package/src/auth/middlewares/index.ts +1 -1
- package/src/auth/middlewares/proxy.ts +10 -2
- package/src/layouts/AppLayout/AppLayout.tsx +9 -7
- package/src/layouts/AppLayout/components/ErrorBoundary.tsx +6 -3
- package/src/layouts/AppLayout/components/PageProgress.tsx +2 -0
- package/src/layouts/AppLayout/components/Seo.tsx +2 -0
- package/src/layouts/AppLayout/components/UpdateNotifier/UpdateNotifier.tsx +3 -2
- package/src/layouts/AppLayout/hooks/index.ts +2 -0
- package/src/layouts/AppLayout/hooks/useNavigation.ts +3 -1
- package/src/layouts/AppLayout/layouts/AdminLayout/AdminLayout.tsx +1 -0
- package/src/layouts/AppLayout/layouts/AuthLayout/AuthContext.tsx +2 -0
- package/src/layouts/AppLayout/layouts/AuthLayout/IdentifierForm.tsx +2 -0
- package/src/layouts/AppLayout/layouts/AuthLayout/OTPForm.tsx +4 -0
- package/src/layouts/AppLayout/layouts/AuthLayout/index.ts +2 -0
- package/src/layouts/AppLayout/layouts/PrivateLayout/PrivateLayout.tsx +1 -0
- package/src/layouts/AppLayout/providers/CoreProviders.tsx +1 -0
- package/src/layouts/PaymentsLayout/PaymentsLayout.tsx +1 -0
- package/src/layouts/PaymentsLayout/components/CreatePaymentDialog.tsx +1 -0
- package/src/layouts/PaymentsLayout/events.ts +2 -0
- package/src/layouts/ProfileLayout/ProfileLayout.tsx +1 -0
- package/src/layouts/ProfileLayout/components/ProfileForm.tsx +1 -0
- package/src/layouts/SimpleLayout/SimpleLayout.tsx +72 -0
- package/src/layouts/SimpleLayout/index.ts +3 -0
- package/src/layouts/SupportLayout/SupportLayout.tsx +1 -0
- package/src/layouts/SupportLayout/components/CreateTicketDialog.tsx +1 -0
- package/src/layouts/SupportLayout/components/TicketList.tsx +6 -5
- package/src/layouts/SupportLayout/events.ts +2 -0
- package/src/layouts/index.ts +1 -3
- package/src/snippets/AuthDialog/useAuthDialog.ts +2 -0
- package/src/snippets/Chat/components/MessageList.tsx +12 -11
- package/src/snippets/Chat/index.tsx +1 -0
- package/src/snippets/ContactForm/ContactForm.tsx +7 -2
- package/src/snippets/ContactForm/ContactPage.tsx +16 -3
- package/src/snippets/VideoPlayer/README.md +35 -0
- package/src/snippets/VideoPlayer/VideoControls.tsx +13 -9
- package/src/snippets/VideoPlayer/VideoPlayer.tsx +159 -25
- package/src/snippets/VideoPlayer/index.ts +1 -1
- package/src/validation/utils/curl-generator.ts +5 -1
- package/src/layouts/UILayout/README.md +0 -267
- package/src/layouts/UILayout/SUMMARY.md +0 -298
- package/src/layouts/UILayout/TOOLS_INTEGRATION.md +0 -216
- package/src/layouts/UILayout/components/AutoComponentDemo.tsx +0 -77
- package/src/layouts/UILayout/components/CategoryRenderer.tsx +0 -45
- package/src/layouts/UILayout/components/TailwindGuideRenderer.tsx +0 -138
- package/src/layouts/UILayout/components/index.ts +0 -15
- package/src/layouts/UILayout/components/layout/Header/CopyAIButton.tsx +0 -58
- package/src/layouts/UILayout/components/layout/Header/Header.tsx +0 -60
- package/src/layouts/UILayout/components/layout/Header/HeaderDesktop.tsx +0 -51
- package/src/layouts/UILayout/components/layout/Header/HeaderMobile.tsx +0 -71
- package/src/layouts/UILayout/components/layout/Header/TestValidationButton.tsx +0 -268
- package/src/layouts/UILayout/components/layout/Header/index.ts +0 -11
- package/src/layouts/UILayout/components/layout/MobileOverlay/MobileOverlay.tsx +0 -47
- package/src/layouts/UILayout/components/layout/MobileOverlay/index.ts +0 -6
- package/src/layouts/UILayout/components/layout/Sidebar/Sidebar.tsx +0 -95
- package/src/layouts/UILayout/components/layout/Sidebar/SidebarCategory.tsx +0 -54
- package/src/layouts/UILayout/components/layout/Sidebar/SidebarContent.tsx +0 -93
- package/src/layouts/UILayout/components/layout/Sidebar/SidebarFooter.tsx +0 -49
- package/src/layouts/UILayout/components/layout/Sidebar/index.ts +0 -9
- package/src/layouts/UILayout/components/layout/index.ts +0 -8
- package/src/layouts/UILayout/components/shared/Badge/CountBadge.tsx +0 -38
- package/src/layouts/UILayout/components/shared/Badge/index.ts +0 -5
- package/src/layouts/UILayout/components/shared/CodeBlock/CodeBlock.tsx +0 -48
- package/src/layouts/UILayout/components/shared/CodeBlock/CopyButton.tsx +0 -49
- package/src/layouts/UILayout/components/shared/CodeBlock/index.ts +0 -6
- package/src/layouts/UILayout/components/shared/Section/Section.tsx +0 -63
- package/src/layouts/UILayout/components/shared/Section/index.ts +0 -5
- package/src/layouts/UILayout/components/shared/index.ts +0 -8
- package/src/layouts/UILayout/config/ai-export.config.ts +0 -89
- package/src/layouts/UILayout/config/categories.config.tsx +0 -122
- package/src/layouts/UILayout/config/components/blocks.config.tsx +0 -239
- package/src/layouts/UILayout/config/components/data.config.tsx +0 -433
- package/src/layouts/UILayout/config/components/feedback.config.tsx +0 -290
- package/src/layouts/UILayout/config/components/forms.config.tsx +0 -996
- package/src/layouts/UILayout/config/components/hooks.config.tsx +0 -168
- package/src/layouts/UILayout/config/components/index.ts +0 -72
- package/src/layouts/UILayout/config/components/layout.config.tsx +0 -246
- package/src/layouts/UILayout/config/components/navigation.config.tsx +0 -352
- package/src/layouts/UILayout/config/components/overlay.config.tsx +0 -569
- package/src/layouts/UILayout/config/components/specialized.config.tsx +0 -400
- package/src/layouts/UILayout/config/components/tools.config.tsx +0 -234
- package/src/layouts/UILayout/config/components/types.ts +0 -14
- package/src/layouts/UILayout/config/index.ts +0 -42
- package/src/layouts/UILayout/config/tailwind.config.ts +0 -131
- package/src/layouts/UILayout/constants.ts +0 -23
- package/src/layouts/UILayout/context/ShowcaseContext.tsx +0 -81
- package/src/layouts/UILayout/context/index.ts +0 -1
- package/src/layouts/UILayout/core/UIGuideApp.client.tsx +0 -18
- package/src/layouts/UILayout/core/UIGuideApp.tsx +0 -33
- package/src/layouts/UILayout/core/UIGuideLanding.tsx +0 -172
- package/src/layouts/UILayout/core/UIGuideView.tsx +0 -61
- package/src/layouts/UILayout/core/UILayout.tsx +0 -125
- package/src/layouts/UILayout/core/UILayoutSidebar.tsx +0 -11
- package/src/layouts/UILayout/core/index.ts +0 -10
- package/src/layouts/UILayout/hooks/index.ts +0 -9
- package/src/layouts/UILayout/hooks/useAIExport.ts +0 -78
- package/src/layouts/UILayout/hooks/useCategoryNavigation.ts +0 -92
- package/src/layouts/UILayout/hooks/useComponentSearch.ts +0 -81
- package/src/layouts/UILayout/hooks/useSidebarState.ts +0 -36
- package/src/layouts/UILayout/index.ts +0 -160
- package/src/layouts/UILayout/types/component.ts +0 -45
- package/src/layouts/UILayout/types/index.ts +0 -23
- package/src/layouts/UILayout/types/layout.ts +0 -57
- package/src/layouts/UILayout/types/navigation.ts +0 -33
- package/src/layouts/UILayout/utils/ai-export/formatters.ts +0 -71
- package/src/layouts/UILayout/utils/ai-export/index.ts +0 -5
- package/src/layouts/UILayout/utils/component-helpers/filter.ts +0 -109
- package/src/layouts/UILayout/utils/component-helpers/index.ts +0 -6
- package/src/layouts/UILayout/utils/component-helpers/search.ts +0 -95
- package/src/layouts/UILayout/utils/index.ts +0 -6
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MobileOverlay Component
|
|
3
|
-
* Dark overlay for mobile sidebar
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
'use client';
|
|
7
|
-
|
|
8
|
-
import React from 'react';
|
|
9
|
-
import { createPortal } from 'react-dom';
|
|
10
|
-
import { cn } from '@djangocfg/ui/lib';
|
|
11
|
-
|
|
12
|
-
export interface MobileOverlayProps {
|
|
13
|
-
/** Is overlay visible */
|
|
14
|
-
isOpen?: boolean;
|
|
15
|
-
/** Close callback */
|
|
16
|
-
onClose?: () => void;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Mobile Overlay
|
|
21
|
-
* Darkens background when mobile sidebar is open
|
|
22
|
-
* Closes sidebar when clicked
|
|
23
|
-
*/
|
|
24
|
-
export function MobileOverlay({ isOpen = false, onClose }: MobileOverlayProps) {
|
|
25
|
-
const [mounted, setMounted] = React.useState(false);
|
|
26
|
-
|
|
27
|
-
React.useEffect(() => {
|
|
28
|
-
setMounted(true);
|
|
29
|
-
}, []);
|
|
30
|
-
|
|
31
|
-
if (!isOpen || !mounted || typeof window === 'undefined') {
|
|
32
|
-
return null;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return createPortal(
|
|
36
|
-
<div
|
|
37
|
-
className={cn(
|
|
38
|
-
'fixed inset-0 z-150 transition-opacity duration-300',
|
|
39
|
-
isOpen ? 'opacity-100' : 'opacity-0 pointer-events-none'
|
|
40
|
-
)}
|
|
41
|
-
style={{ backgroundColor: 'rgb(0 0 0 / 0.5)' }}
|
|
42
|
-
onClick={onClose}
|
|
43
|
-
aria-hidden="true"
|
|
44
|
-
/>,
|
|
45
|
-
document.body
|
|
46
|
-
);
|
|
47
|
-
}
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sidebar Component
|
|
3
|
-
* Navigation sidebar for component categories
|
|
4
|
-
* Desktop: sticky with react-sticky-box
|
|
5
|
-
* Mobile: Drawer component (Vaul-based)
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
'use client';
|
|
9
|
-
|
|
10
|
-
import React from 'react';
|
|
11
|
-
import { useIsMobile, Sticky, Drawer, DrawerContent } from '@djangocfg/ui';
|
|
12
|
-
import type { ComponentCategory } from '../../../types';
|
|
13
|
-
import { SidebarContent } from './SidebarContent';
|
|
14
|
-
|
|
15
|
-
export interface SidebarProps {
|
|
16
|
-
/** Available categories */
|
|
17
|
-
categories: ComponentCategory[];
|
|
18
|
-
/** Current selected category */
|
|
19
|
-
currentCategory?: string;
|
|
20
|
-
/** Category change callback */
|
|
21
|
-
onCategoryChange?: (categoryId: string) => void;
|
|
22
|
-
/** Is sidebar open (mobile only) */
|
|
23
|
-
isOpen?: boolean;
|
|
24
|
-
/** Close sidebar callback (mobile only) */
|
|
25
|
-
onClose?: () => void;
|
|
26
|
-
/** Function to generate AI context */
|
|
27
|
-
onCopyForAI?: () => string;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Sidebar Component
|
|
32
|
-
* Desktop: Always visible static sidebar
|
|
33
|
-
* Mobile: Drawer-based sidebar with slide animation
|
|
34
|
-
*/
|
|
35
|
-
export function Sidebar({
|
|
36
|
-
categories,
|
|
37
|
-
currentCategory,
|
|
38
|
-
onCategoryChange,
|
|
39
|
-
isOpen = false,
|
|
40
|
-
onClose,
|
|
41
|
-
onCopyForAI,
|
|
42
|
-
}: SidebarProps) {
|
|
43
|
-
const isMobile = useIsMobile();
|
|
44
|
-
|
|
45
|
-
// Desktop sidebar - uses react-sticky-box via Sticky component
|
|
46
|
-
// Sticks to viewport top (with navbar offset) but stops at parent container boundary (footer)
|
|
47
|
-
// Parent UILayout has isolate + zIndex:0 to prevent overlapping navbar
|
|
48
|
-
if (!isMobile) {
|
|
49
|
-
return (
|
|
50
|
-
<div
|
|
51
|
-
className="w-64 flex-shrink-0 self-stretch bg-background"
|
|
52
|
-
style={{ boxShadow: '-1px 0 0 0 hsl(var(--border))' }}
|
|
53
|
-
>
|
|
54
|
-
<Sticky
|
|
55
|
-
offsetTop={56}
|
|
56
|
-
offsetBottom={0}
|
|
57
|
-
disableOnMobile={false}
|
|
58
|
-
className="w-64"
|
|
59
|
-
>
|
|
60
|
-
<aside
|
|
61
|
-
className="overflow-y-auto w-64 bg-background"
|
|
62
|
-
style={{ maxHeight: 'calc(100vh - 56px)' }}
|
|
63
|
-
>
|
|
64
|
-
<SidebarContent
|
|
65
|
-
categories={categories}
|
|
66
|
-
currentCategory={currentCategory}
|
|
67
|
-
onCategoryChange={onCategoryChange}
|
|
68
|
-
isMobile={false}
|
|
69
|
-
onCopyForAI={onCopyForAI}
|
|
70
|
-
/>
|
|
71
|
-
</aside>
|
|
72
|
-
</Sticky>
|
|
73
|
-
</div>
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Mobile sidebar - uses Drawer component (Vaul-based)
|
|
78
|
-
return (
|
|
79
|
-
<Drawer
|
|
80
|
-
open={isOpen}
|
|
81
|
-
onOpenChange={(open) => !open && onClose?.()}
|
|
82
|
-
direction="right"
|
|
83
|
-
>
|
|
84
|
-
<DrawerContent direction="right" className="w-64">
|
|
85
|
-
<SidebarContent
|
|
86
|
-
categories={categories}
|
|
87
|
-
currentCategory={currentCategory}
|
|
88
|
-
onCategoryChange={onCategoryChange}
|
|
89
|
-
isMobile={true}
|
|
90
|
-
onCopyForAI={onCopyForAI}
|
|
91
|
-
/>
|
|
92
|
-
</DrawerContent>
|
|
93
|
-
</Drawer>
|
|
94
|
-
);
|
|
95
|
-
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SidebarCategory Component
|
|
3
|
-
* Single category item in sidebar navigation
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
'use client';
|
|
7
|
-
|
|
8
|
-
import React from 'react';
|
|
9
|
-
import { cn } from '@djangocfg/ui/lib';
|
|
10
|
-
import type { ComponentCategory } from '../../../types';
|
|
11
|
-
import { CountBadge } from '../../shared/Badge';
|
|
12
|
-
|
|
13
|
-
interface SidebarCategoryProps {
|
|
14
|
-
/** Category data */
|
|
15
|
-
category: ComponentCategory;
|
|
16
|
-
/** Is this category active */
|
|
17
|
-
active?: boolean;
|
|
18
|
-
/** Click handler */
|
|
19
|
-
onClick?: () => void;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Sidebar Category Item
|
|
24
|
-
* Displays a category with icon, label, and optional count badge
|
|
25
|
-
*/
|
|
26
|
-
export function SidebarCategory({
|
|
27
|
-
category,
|
|
28
|
-
active = false,
|
|
29
|
-
onClick,
|
|
30
|
-
}: SidebarCategoryProps) {
|
|
31
|
-
return (
|
|
32
|
-
<button
|
|
33
|
-
onClick={onClick}
|
|
34
|
-
className={cn(
|
|
35
|
-
'w-full flex items-center gap-3 px-3 py-2 rounded-md text-sm font-medium transition-colors',
|
|
36
|
-
active
|
|
37
|
-
? 'bg-primary text-primary-foreground'
|
|
38
|
-
: 'text-muted-foreground hover:bg-muted hover:text-foreground'
|
|
39
|
-
)}
|
|
40
|
-
title={category.description}
|
|
41
|
-
>
|
|
42
|
-
{/* Icon */}
|
|
43
|
-
<span className="flex-shrink-0">{category.icon}</span>
|
|
44
|
-
|
|
45
|
-
{/* Label */}
|
|
46
|
-
<span className="flex-1 text-left break-words">{category.label}</span>
|
|
47
|
-
|
|
48
|
-
{/* Count Badge */}
|
|
49
|
-
{category.count !== undefined && (
|
|
50
|
-
<CountBadge count={category.count} active={active} />
|
|
51
|
-
)}
|
|
52
|
-
</button>
|
|
53
|
-
);
|
|
54
|
-
}
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SidebarContent Component
|
|
3
|
-
* Main content of the sidebar (logo, navigation, footer)
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
'use client';
|
|
7
|
-
|
|
8
|
-
import React from 'react';
|
|
9
|
-
import type { ComponentCategory } from '../../../types';
|
|
10
|
-
import { SidebarCategory } from './SidebarCategory';
|
|
11
|
-
import { CopyAIButton } from '../Header/CopyAIButton';
|
|
12
|
-
import { TestValidationButton } from '../Header/TestValidationButton';
|
|
13
|
-
|
|
14
|
-
interface SidebarContentProps {
|
|
15
|
-
/** Available categories */
|
|
16
|
-
categories: ComponentCategory[];
|
|
17
|
-
/** Current selected category */
|
|
18
|
-
currentCategory?: string;
|
|
19
|
-
/** Category change callback */
|
|
20
|
-
onCategoryChange?: (categoryId: string) => void;
|
|
21
|
-
/** Is mobile view */
|
|
22
|
-
isMobile: boolean;
|
|
23
|
-
/** Function to generate AI context */
|
|
24
|
-
onCopyForAI?: () => string;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Sidebar Content
|
|
29
|
-
* Contains logo (desktop only), navigation, and footer
|
|
30
|
-
*/
|
|
31
|
-
export function SidebarContent({
|
|
32
|
-
categories,
|
|
33
|
-
currentCategory,
|
|
34
|
-
onCategoryChange,
|
|
35
|
-
isMobile,
|
|
36
|
-
onCopyForAI,
|
|
37
|
-
}: SidebarContentProps) {
|
|
38
|
-
return (
|
|
39
|
-
<div className="flex flex-col h-full overflow-hidden">
|
|
40
|
-
|
|
41
|
-
{/* Developer Tools */}
|
|
42
|
-
{!isMobile && (
|
|
43
|
-
<div className="border-b flex-shrink-0 px-4 py-3 flex gap-2">
|
|
44
|
-
{onCopyForAI && (
|
|
45
|
-
<CopyAIButton
|
|
46
|
-
onCopyForAI={onCopyForAI}
|
|
47
|
-
size="sm"
|
|
48
|
-
showLabel
|
|
49
|
-
className="flex-1"
|
|
50
|
-
/>
|
|
51
|
-
)}
|
|
52
|
-
<TestValidationButton
|
|
53
|
-
size="sm"
|
|
54
|
-
showLabel={false}
|
|
55
|
-
/>
|
|
56
|
-
</div>
|
|
57
|
-
)}
|
|
58
|
-
|
|
59
|
-
{/* Navigation */}
|
|
60
|
-
<div className="flex-1 overflow-y-auto scrollbar-thin">
|
|
61
|
-
<div className="p-4">
|
|
62
|
-
<nav>
|
|
63
|
-
{/* Section Header */}
|
|
64
|
-
<div className="mb-4">
|
|
65
|
-
<h3 className="mb-2 px-2 text-xs font-semibold text-muted-foreground uppercase tracking-wider">
|
|
66
|
-
Component Categories
|
|
67
|
-
</h3>
|
|
68
|
-
</div>
|
|
69
|
-
|
|
70
|
-
{/* Categories List */}
|
|
71
|
-
<div className="space-y-1">
|
|
72
|
-
{categories.map((category) => (
|
|
73
|
-
<SidebarCategory
|
|
74
|
-
key={category.id}
|
|
75
|
-
category={category}
|
|
76
|
-
active={currentCategory === category.id}
|
|
77
|
-
onClick={() => onCategoryChange?.(category.id)}
|
|
78
|
-
/>
|
|
79
|
-
))}
|
|
80
|
-
</div>
|
|
81
|
-
</nav>
|
|
82
|
-
</div>
|
|
83
|
-
</div>
|
|
84
|
-
|
|
85
|
-
{/* Footer */}
|
|
86
|
-
<div className="border-t p-4 bg-muted/30">
|
|
87
|
-
<p className="text-xs text-muted-foreground">
|
|
88
|
-
Built with Tailwind CSS v4
|
|
89
|
-
</p>
|
|
90
|
-
</div>
|
|
91
|
-
</div>
|
|
92
|
-
);
|
|
93
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SidebarFooter Component
|
|
3
|
-
* Footer section with developer tools (Copy for AI, Test Validation)
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
'use client';
|
|
7
|
-
|
|
8
|
-
import React from 'react';
|
|
9
|
-
import { CopyAIButton } from '../Header/CopyAIButton';
|
|
10
|
-
import { TestValidationButton } from '../Header/TestValidationButton';
|
|
11
|
-
|
|
12
|
-
export interface SidebarFooterProps {
|
|
13
|
-
/** Function to generate AI context */
|
|
14
|
-
onCopyForAI?: () => string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Sidebar Footer
|
|
19
|
-
* Developer tools: Copy for AI and Test Validation buttons
|
|
20
|
-
*/
|
|
21
|
-
export function SidebarFooter({ onCopyForAI }: SidebarFooterProps) {
|
|
22
|
-
return (
|
|
23
|
-
<div className="border-t p-4 bg-muted/30 space-y-3">
|
|
24
|
-
{/* Developer Tools */}
|
|
25
|
-
<div className="flex flex-col gap-2">
|
|
26
|
-
{onCopyForAI && (
|
|
27
|
-
<CopyAIButton
|
|
28
|
-
onCopyForAI={onCopyForAI}
|
|
29
|
-
size="sm"
|
|
30
|
-
showLabel
|
|
31
|
-
className="w-full justify-start"
|
|
32
|
-
/>
|
|
33
|
-
)}
|
|
34
|
-
<TestValidationButton
|
|
35
|
-
size="sm"
|
|
36
|
-
showLabel
|
|
37
|
-
className="w-full justify-start"
|
|
38
|
-
/>
|
|
39
|
-
</div>
|
|
40
|
-
|
|
41
|
-
{/* Tailwind v4 info */}
|
|
42
|
-
<div className="pt-2 border-t border-border/50">
|
|
43
|
-
<p className="text-xs text-muted-foreground">
|
|
44
|
-
Built with Tailwind CSS v4
|
|
45
|
-
</p>
|
|
46
|
-
</div>
|
|
47
|
-
</div>
|
|
48
|
-
);
|
|
49
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sidebar Components
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export { Sidebar } from './Sidebar';
|
|
6
|
-
export type { SidebarProps } from './Sidebar';
|
|
7
|
-
export { SidebarContent } from './SidebarContent';
|
|
8
|
-
export { SidebarCategory } from './SidebarCategory';
|
|
9
|
-
export { SidebarFooter } from './SidebarFooter';
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CountBadge Component
|
|
3
|
-
* Badge for displaying count numbers
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
'use client';
|
|
7
|
-
|
|
8
|
-
import React from 'react';
|
|
9
|
-
import { cn } from '@djangocfg/ui/lib';
|
|
10
|
-
|
|
11
|
-
interface CountBadgeProps {
|
|
12
|
-
/** Count to display */
|
|
13
|
-
count: number;
|
|
14
|
-
/** Is active/selected */
|
|
15
|
-
active?: boolean;
|
|
16
|
-
/** Custom class name */
|
|
17
|
-
className?: string;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Count Badge
|
|
22
|
-
* Displays a count number with optional active state
|
|
23
|
-
*/
|
|
24
|
-
export function CountBadge({ count, active = false, className }: CountBadgeProps) {
|
|
25
|
-
return (
|
|
26
|
-
<span
|
|
27
|
-
className={cn(
|
|
28
|
-
'text-xs px-2 py-0.5 rounded-full flex-shrink-0',
|
|
29
|
-
active
|
|
30
|
-
? 'bg-primary-foreground/20 text-primary-foreground'
|
|
31
|
-
: 'bg-muted text-muted-foreground',
|
|
32
|
-
className
|
|
33
|
-
)}
|
|
34
|
-
>
|
|
35
|
-
{count}
|
|
36
|
-
</span>
|
|
37
|
-
);
|
|
38
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CodeBlock Component
|
|
3
|
-
* Displays code with syntax highlighting and copy button
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
'use client';
|
|
7
|
-
|
|
8
|
-
import React from 'react';
|
|
9
|
-
import { cn } from '@djangocfg/ui/lib';
|
|
10
|
-
import { CopyButton } from './CopyButton';
|
|
11
|
-
|
|
12
|
-
interface CodeBlockProps {
|
|
13
|
-
/** Code to display */
|
|
14
|
-
code: string;
|
|
15
|
-
/** Programming language */
|
|
16
|
-
language?: string;
|
|
17
|
-
/** Show copy button */
|
|
18
|
-
showCopy?: boolean;
|
|
19
|
-
/** Custom class name */
|
|
20
|
-
className?: string;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Code Block
|
|
25
|
-
* Displays formatted code with optional copy functionality
|
|
26
|
-
*/
|
|
27
|
-
export function CodeBlock({
|
|
28
|
-
code,
|
|
29
|
-
language = 'tsx',
|
|
30
|
-
showCopy = true,
|
|
31
|
-
className,
|
|
32
|
-
}: CodeBlockProps) {
|
|
33
|
-
return (
|
|
34
|
-
<div className={cn('relative group', className)}>
|
|
35
|
-
{/* Copy Button */}
|
|
36
|
-
{showCopy && (
|
|
37
|
-
<div className="absolute right-2 top-2 opacity-0 group-hover:opacity-100 transition-opacity">
|
|
38
|
-
<CopyButton code={code} />
|
|
39
|
-
</div>
|
|
40
|
-
)}
|
|
41
|
-
|
|
42
|
-
{/* Code Display */}
|
|
43
|
-
<pre className="bg-muted/50 rounded-lg p-4 overflow-x-auto">
|
|
44
|
-
<code className={`language-${language} text-sm`}>{code}</code>
|
|
45
|
-
</pre>
|
|
46
|
-
</div>
|
|
47
|
-
);
|
|
48
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CopyButton Component
|
|
3
|
-
* Button for copying code to clipboard
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
'use client';
|
|
7
|
-
|
|
8
|
-
import React, { useState } from 'react';
|
|
9
|
-
import { Button } from '@djangocfg/ui';
|
|
10
|
-
import { Copy, Check } from 'lucide-react';
|
|
11
|
-
import { useCopy } from '@djangocfg/ui';
|
|
12
|
-
|
|
13
|
-
interface CopyButtonProps {
|
|
14
|
-
/** Code to copy */
|
|
15
|
-
code: string;
|
|
16
|
-
/** Button size */
|
|
17
|
-
size?: 'sm' | 'default' | 'lg';
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Copy Button
|
|
22
|
-
* Shows check icon after successful copy
|
|
23
|
-
*/
|
|
24
|
-
export function CopyButton({ code, size = 'sm' }: CopyButtonProps) {
|
|
25
|
-
const [copied, setCopied] = useState(false);
|
|
26
|
-
const { copyToClipboard } = useCopy();
|
|
27
|
-
|
|
28
|
-
const handleCopy = async () => {
|
|
29
|
-
await copyToClipboard(code);
|
|
30
|
-
setCopied(true);
|
|
31
|
-
setTimeout(() => setCopied(false), 2000);
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
return (
|
|
35
|
-
<Button
|
|
36
|
-
variant="ghost"
|
|
37
|
-
size={size}
|
|
38
|
-
onClick={handleCopy}
|
|
39
|
-
className="h-8 w-8 p-0"
|
|
40
|
-
aria-label="Copy code"
|
|
41
|
-
>
|
|
42
|
-
{copied ? (
|
|
43
|
-
<Check className="h-4 w-4 text-green-500" />
|
|
44
|
-
) : (
|
|
45
|
-
<Copy className="h-4 w-4" />
|
|
46
|
-
)}
|
|
47
|
-
</Button>
|
|
48
|
-
);
|
|
49
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Section Component
|
|
3
|
-
* Reusable section with title and optional description
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
'use client';
|
|
7
|
-
|
|
8
|
-
import React, { ReactNode } from 'react';
|
|
9
|
-
import { cn } from '@djangocfg/ui/lib';
|
|
10
|
-
|
|
11
|
-
interface SectionProps {
|
|
12
|
-
/** Section title */
|
|
13
|
-
title?: string;
|
|
14
|
-
/** Section description */
|
|
15
|
-
description?: string;
|
|
16
|
-
/** Section content */
|
|
17
|
-
children: ReactNode;
|
|
18
|
-
/** Custom class name */
|
|
19
|
-
className?: string;
|
|
20
|
-
/** Title class name */
|
|
21
|
-
titleClassName?: string;
|
|
22
|
-
/** Content class name */
|
|
23
|
-
contentClassName?: string;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Section Component
|
|
28
|
-
* Displays a section with optional title and description
|
|
29
|
-
*/
|
|
30
|
-
export function Section({
|
|
31
|
-
title,
|
|
32
|
-
description,
|
|
33
|
-
children,
|
|
34
|
-
className,
|
|
35
|
-
titleClassName,
|
|
36
|
-
contentClassName,
|
|
37
|
-
}: SectionProps) {
|
|
38
|
-
return (
|
|
39
|
-
<section className={cn('space-y-4', className)}>
|
|
40
|
-
{/* Header */}
|
|
41
|
-
{(title || description) && (
|
|
42
|
-
<div className="space-y-1">
|
|
43
|
-
{title && (
|
|
44
|
-
<h2
|
|
45
|
-
className={cn(
|
|
46
|
-
'text-2xl font-bold tracking-tight',
|
|
47
|
-
titleClassName
|
|
48
|
-
)}
|
|
49
|
-
>
|
|
50
|
-
{title}
|
|
51
|
-
</h2>
|
|
52
|
-
)}
|
|
53
|
-
{description && (
|
|
54
|
-
<p className="text-sm text-muted-foreground">{description}</p>
|
|
55
|
-
)}
|
|
56
|
-
</div>
|
|
57
|
-
)}
|
|
58
|
-
|
|
59
|
-
{/* Content */}
|
|
60
|
-
<div className={contentClassName}>{children}</div>
|
|
61
|
-
</section>
|
|
62
|
-
);
|
|
63
|
-
}
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AI Export Configuration
|
|
3
|
-
* Generates formatted documentation for AI consumption
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { COMPONENTS_CONFIG, getAllCategories } from './components';
|
|
7
|
-
import { TAILWIND_GUIDE } from './tailwind.config';
|
|
8
|
-
|
|
9
|
-
export interface UILibraryConfig {
|
|
10
|
-
projectName: string;
|
|
11
|
-
version: string;
|
|
12
|
-
description: string;
|
|
13
|
-
totalComponents: number;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export const UI_LIBRARY_CONFIG: UILibraryConfig = {
|
|
17
|
-
projectName: "Django CFG UI",
|
|
18
|
-
version: "1.0.0",
|
|
19
|
-
description: "Comprehensive React UI library with 56+ components, 7 blocks, and 11 hooks built with Radix UI, Tailwind CSS v4, and TypeScript",
|
|
20
|
-
totalComponents: COMPONENTS_CONFIG.length,
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Generate formatted text for AI consumption
|
|
25
|
-
* This is the single source of truth that gets copied to clipboard
|
|
26
|
-
*/
|
|
27
|
-
export function generateAIContext(): string {
|
|
28
|
-
const { projectName, version, description } = UI_LIBRARY_CONFIG;
|
|
29
|
-
|
|
30
|
-
let output = `# ${projectName} v${version}\n\n`;
|
|
31
|
-
output += `${description}\n\n`;
|
|
32
|
-
|
|
33
|
-
// Quick Reference - Available Components
|
|
34
|
-
output += `## 📋 Quick Reference - Available Components\n\n`;
|
|
35
|
-
const categories = getAllCategories();
|
|
36
|
-
categories.forEach(category => {
|
|
37
|
-
const comps = COMPONENTS_CONFIG.filter(comp => comp.category === category);
|
|
38
|
-
const componentNames = comps.map(c => c.name).join(', ');
|
|
39
|
-
output += `### ${category.charAt(0).toUpperCase() + category.slice(1)} (${comps.length})\n`;
|
|
40
|
-
output += `${componentNames}\n\n`;
|
|
41
|
-
});
|
|
42
|
-
output += `---\n\n`;
|
|
43
|
-
|
|
44
|
-
// Tailwind 4 Guide
|
|
45
|
-
output += `## Tailwind CSS v${TAILWIND_GUIDE.version} Guidelines\n\n`;
|
|
46
|
-
|
|
47
|
-
output += `### Key Changes\n`;
|
|
48
|
-
TAILWIND_GUIDE.keyChanges.forEach(change => {
|
|
49
|
-
output += `- ${change}\n`;
|
|
50
|
-
});
|
|
51
|
-
output += `\n`;
|
|
52
|
-
|
|
53
|
-
output += `### Best Practices\n`;
|
|
54
|
-
TAILWIND_GUIDE.bestPractices.forEach(practice => {
|
|
55
|
-
output += `- ${practice}\n`;
|
|
56
|
-
});
|
|
57
|
-
output += `\n`;
|
|
58
|
-
|
|
59
|
-
output += `### Migration Steps\n`;
|
|
60
|
-
TAILWIND_GUIDE.migrationSteps.forEach((step, index) => {
|
|
61
|
-
output += `${index + 1}. ${step}\n`;
|
|
62
|
-
});
|
|
63
|
-
output += `\n`;
|
|
64
|
-
|
|
65
|
-
output += `### Examples\n\n`;
|
|
66
|
-
TAILWIND_GUIDE.examples.forEach(example => {
|
|
67
|
-
output += `#### ${example.title}\n`;
|
|
68
|
-
output += `${example.description}\n\n`;
|
|
69
|
-
output += `\`\`\`css\n${example.code}\n\`\`\`\n\n`;
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
// Components by Category
|
|
73
|
-
categories.forEach(category => {
|
|
74
|
-
const comps = COMPONENTS_CONFIG.filter(comp => comp.category === category);
|
|
75
|
-
|
|
76
|
-
output += `## ${category.charAt(0).toUpperCase() + category.slice(1)} (${comps.length})\n\n`;
|
|
77
|
-
|
|
78
|
-
comps.forEach(comp => {
|
|
79
|
-
output += `### ${comp.name}\n`;
|
|
80
|
-
output += `${comp.description}\n\n`;
|
|
81
|
-
output += `\`\`\`tsx\n`;
|
|
82
|
-
output += `${comp.importPath}\n\n`;
|
|
83
|
-
output += `${comp.example}\n`;
|
|
84
|
-
output += `\`\`\`\n\n`;
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
return output;
|
|
89
|
-
}
|