@djangocfg/ui-nextjs 2.1.320 → 2.1.321

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.
@@ -1,130 +0,0 @@
1
- import { Link } from '@djangocfg/ui-core/components';
2
- import React from 'react';
3
-
4
- import {
5
- Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage,
6
- BreadcrumbSeparator
7
- } from './breadcrumb';
8
-
9
- export interface BreadcrumbItem {
10
- label: string;
11
- href?: string;
12
- /**
13
- * Force render as current page (non-interactive, aria-current="page").
14
- * By default only the last item without href is treated as current page.
15
- */
16
- isCurrentPage?: boolean;
17
- icon?: React.ReactNode;
18
- }
19
-
20
- export interface BreadcrumbNavigationProps {
21
- items: BreadcrumbItem[];
22
- separator?: React.ReactNode;
23
- /**
24
- * Max visible items (excluding the ellipsis slot) before collapsing.
25
- * Must be >= 2. Defaults to 5.
26
- */
27
- maxItems?: number;
28
- className?: string;
29
- }
30
-
31
- type DisplayEntry =
32
- | { type: 'item'; item: BreadcrumbItem; originalIndex: number }
33
- | { type: 'ellipsis' };
34
-
35
- export const BreadcrumbNavigation: React.FC<BreadcrumbNavigationProps> = ({
36
- items,
37
- separator,
38
- maxItems = 5,
39
- className,
40
- }) => {
41
- if (!items || items.length === 0) return null;
42
-
43
- const clampedMax = Math.max(2, maxItems);
44
-
45
- // Build the list of entries to render
46
- const entries: DisplayEntry[] = (() => {
47
- if (items.length <= clampedMax) {
48
- return items.map((item, i) => ({ type: 'item' as const, item, originalIndex: i }));
49
- }
50
- // Always show first item, ellipsis, then last (clampedMax - 2) items
51
- // e.g. maxItems=4 → show 1 + ellipsis + 2 last = 4 visible items + ellipsis
52
- const tailCount = Math.max(1, clampedMax - 2);
53
- const tail = items.slice(-tailCount).map((item, i) => ({
54
- type: 'item' as const,
55
- item,
56
- originalIndex: items.length - tailCount + i,
57
- }));
58
- return [
59
- { type: 'item' as const, item: items[0]!, originalIndex: 0 },
60
- { type: 'ellipsis' as const },
61
- ...tail,
62
- ];
63
- })();
64
-
65
- const resolveIsCurrentPage = (item: BreadcrumbItem, originalIndex: number): boolean => {
66
- if (item.isCurrentPage !== undefined) return item.isCurrentPage;
67
- return originalIndex === items.length - 1;
68
- };
69
-
70
- const renderItem = (item: BreadcrumbItem, originalIndex: number) => {
71
- const current = resolveIsCurrentPage(item, originalIndex);
72
-
73
- const content = (
74
- <>
75
- {item.icon && <span className="mr-1">{item.icon}</span>}
76
- {item.label}
77
- </>
78
- );
79
-
80
- if (current) {
81
- return (
82
- <BreadcrumbItem key={`item-${originalIndex}`}>
83
- <BreadcrumbPage>{content}</BreadcrumbPage>
84
- </BreadcrumbItem>
85
- );
86
- }
87
-
88
- return (
89
- <BreadcrumbItem key={`item-${originalIndex}`}>
90
- {item.href ? (
91
- <BreadcrumbLink asChild>
92
- <Link href={item.href}>{content}</Link>
93
- </BreadcrumbLink>
94
- ) : (
95
- <BreadcrumbLink>{content}</BreadcrumbLink>
96
- )}
97
- </BreadcrumbItem>
98
- );
99
- };
100
-
101
- return (
102
- <Breadcrumb className={className}>
103
- <BreadcrumbList>
104
- {entries.map((entry, displayIndex) => {
105
- const isFirst = displayIndex === 0;
106
-
107
- if (entry.type === 'ellipsis') {
108
- return (
109
- <React.Fragment key="ellipsis">
110
- <BreadcrumbSeparator>{separator}</BreadcrumbSeparator>
111
- <BreadcrumbItem>
112
- <BreadcrumbEllipsis />
113
- </BreadcrumbItem>
114
- </React.Fragment>
115
- );
116
- }
117
-
118
- return (
119
- <React.Fragment key={`fragment-${entry.originalIndex}`}>
120
- {!isFirst && <BreadcrumbSeparator>{separator}</BreadcrumbSeparator>}
121
- {renderItem(entry.item, entry.originalIndex)}
122
- </React.Fragment>
123
- );
124
- })}
125
- </BreadcrumbList>
126
- </Breadcrumb>
127
- );
128
- };
129
-
130
- BreadcrumbNavigation.displayName = 'BreadcrumbNavigation';
@@ -1,133 +0,0 @@
1
- "use client"
2
-
3
- import { ChevronRight, MoreHorizontal } from 'lucide-react';
4
- import * as React from 'react';
5
-
6
- import { Link } from '@djangocfg/ui-core/components';
7
- import { cn } from '@djangocfg/ui-core/lib';
8
- import { Slot } from '@radix-ui/react-slot';
9
-
10
- const Breadcrumb = React.forwardRef<
11
- HTMLElement,
12
- React.ComponentPropsWithoutRef<"nav"> & {
13
- separator?: React.ReactNode
14
- }
15
- >(({ ...props }, ref) => <nav ref={ref} aria-label="breadcrumb" {...props} />)
16
- Breadcrumb.displayName = "Breadcrumb"
17
-
18
- const BreadcrumbList = React.forwardRef<
19
- HTMLOListElement,
20
- React.ComponentPropsWithoutRef<"ol">
21
- >(({ className, ...props }, ref) => (
22
- <ol
23
- ref={ref}
24
- className={cn(
25
- "flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5",
26
- className
27
- )}
28
- {...props}
29
- />
30
- ))
31
- BreadcrumbList.displayName = "BreadcrumbList"
32
-
33
- const BreadcrumbItem = React.forwardRef<
34
- HTMLLIElement,
35
- React.ComponentPropsWithoutRef<"li"> & { key?: React.Key }
36
- >(({ className, ...props }, ref) => (
37
- <li
38
- ref={ref}
39
- className={cn("inline-flex items-center gap-1.5", className)}
40
- {...props}
41
- />
42
- ))
43
- BreadcrumbItem.displayName = "BreadcrumbItem"
44
-
45
- const BreadcrumbLink = React.forwardRef<
46
- HTMLAnchorElement,
47
- React.ComponentPropsWithoutRef<"a"> & {
48
- asChild?: boolean
49
- href?: string
50
- }
51
- >(({ asChild, className, href, children, ...props }, ref) => {
52
- const Comp = asChild ? Slot : "a"
53
-
54
- if (href) {
55
- return (
56
- <Link
57
- href={href}
58
- className={cn("transition-colors hover:text-foreground", className)}
59
- ref={ref}
60
- >
61
- {children}
62
- </Link>
63
- )
64
- }
65
-
66
- return (
67
- <Comp
68
- ref={ref}
69
- className={cn("transition-colors hover:text-foreground", className)}
70
- {...props}
71
- >
72
- {children}
73
- </Comp>
74
- )
75
- })
76
- BreadcrumbLink.displayName = "BreadcrumbLink"
77
-
78
- const BreadcrumbPage = React.forwardRef<
79
- HTMLSpanElement,
80
- React.ComponentPropsWithoutRef<"span">
81
- >(({ className, ...props }, ref) => (
82
- <span
83
- ref={ref}
84
- role="link"
85
- aria-disabled="true"
86
- aria-current="page"
87
- className={cn("font-normal text-foreground", className)}
88
- {...props}
89
- />
90
- ))
91
- BreadcrumbPage.displayName = "BreadcrumbPage"
92
-
93
- const BreadcrumbSeparator = ({
94
- children,
95
- className,
96
- ...props
97
- }: React.ComponentProps<"li"> & { key?: React.Key }) => (
98
- <li
99
- role="presentation"
100
- aria-hidden="true"
101
- className={cn("[&>svg]:w-3.5 [&>svg]:h-3.5", className)}
102
- {...props}
103
- >
104
- {children ?? <ChevronRight />}
105
- </li>
106
- )
107
- BreadcrumbSeparator.displayName = "BreadcrumbSeparator"
108
-
109
- const BreadcrumbEllipsis = ({
110
- className,
111
- ...props
112
- }: React.ComponentProps<"span">) => (
113
- <span
114
- role="presentation"
115
- aria-hidden="true"
116
- className={cn("flex h-9 w-9 items-center justify-center", className)}
117
- {...props}
118
- >
119
- <MoreHorizontal className="h-4 w-4" />
120
- <span className="sr-only">More</span>
121
- </span>
122
- )
123
- BreadcrumbEllipsis.displayName = "BreadcrumbElipssis"
124
-
125
- export {
126
- Breadcrumb,
127
- BreadcrumbList,
128
- BreadcrumbItem,
129
- BreadcrumbLink,
130
- BreadcrumbPage,
131
- BreadcrumbSeparator,
132
- BreadcrumbEllipsis,
133
- }
@@ -1,220 +0,0 @@
1
- "use client"
2
-
3
- import { Check, ChevronRight, Circle } from 'lucide-react';
4
- import * as React from 'react';
5
-
6
- import { Link } from '@djangocfg/ui-core/components';
7
- import { cn } from '@djangocfg/ui-core/lib';
8
- import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
9
-
10
- const DropdownMenu = DropdownMenuPrimitive.Root
11
-
12
- const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger
13
-
14
- const DropdownMenuGroup = DropdownMenuPrimitive.Group
15
-
16
- const DropdownMenuPortal = DropdownMenuPrimitive.Portal
17
-
18
- const DropdownMenuSub = DropdownMenuPrimitive.Sub
19
-
20
- const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup
21
-
22
- const DropdownMenuSubTrigger = React.forwardRef<
23
- React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
24
- React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
25
- inset?: boolean
26
- }
27
- >(({ className, inset, children, ...props }, ref) => (
28
- <DropdownMenuPrimitive.SubTrigger
29
- ref={ref}
30
- className={cn(
31
- "flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
32
- inset && "pl-8",
33
- className
34
- )}
35
- {...props}
36
- >
37
- {children}
38
- <ChevronRight className="ml-auto" />
39
- </DropdownMenuPrimitive.SubTrigger>
40
- ))
41
- DropdownMenuSubTrigger.displayName =
42
- DropdownMenuPrimitive.SubTrigger.displayName
43
-
44
- const DropdownMenuSubContent = React.forwardRef<
45
- React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
46
- React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
47
- >(({ className, ...props }, ref) => (
48
- <DropdownMenuPrimitive.SubContent
49
- ref={ref}
50
- className={cn(
51
- "z-600 min-w-32 overflow-hidden rounded-sm border bg-popover backdrop-blur-xl p-1 text-popover-foreground shadow-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
52
- className
53
- )}
54
- {...props}
55
- />
56
- ))
57
- DropdownMenuSubContent.displayName =
58
- DropdownMenuPrimitive.SubContent.displayName
59
-
60
- const DropdownMenuContent = React.forwardRef<
61
- React.ElementRef<typeof DropdownMenuPrimitive.Content>,
62
- React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
63
- >(({ className, sideOffset = 4, ...props }, ref) => (
64
- <DropdownMenuPrimitive.Portal>
65
- <DropdownMenuPrimitive.Content
66
- ref={ref}
67
- sideOffset={sideOffset}
68
- className={cn(
69
- "z-600 max-h-[var(--radix-dropdown-menu-content-available-height)] min-w-32 overflow-y-auto overflow-x-hidden rounded-sm border bg-popover backdrop-blur-xl p-1 text-popover-foreground shadow-sm",
70
- "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
71
- className
72
- )}
73
- {...props}
74
- />
75
- </DropdownMenuPrimitive.Portal>
76
- ))
77
- DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName
78
-
79
- const DropdownMenuItem = React.forwardRef<
80
- React.ElementRef<typeof DropdownMenuPrimitive.Item>,
81
- React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
82
- inset?: boolean
83
- href?: string
84
- key?: React.Key
85
- }
86
- >(({ className, inset, href, children, ...props }, ref) => {
87
- const classes = cn(
88
- "relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0",
89
- inset && "pl-8",
90
- className
91
- )
92
-
93
- if (href) {
94
- return (
95
- <DropdownMenuPrimitive.Item asChild ref={ref} {...props}>
96
- <Link href={href} className={classes}>
97
- {children}
98
- </Link>
99
- </DropdownMenuPrimitive.Item>
100
- )
101
- }
102
-
103
- return (
104
- <DropdownMenuPrimitive.Item
105
- ref={ref}
106
- className={classes}
107
- {...props}
108
- >
109
- {children}
110
- </DropdownMenuPrimitive.Item>
111
- )
112
- })
113
- DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName
114
-
115
- const DropdownMenuCheckboxItem = React.forwardRef<
116
- React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
117
- React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem> & { key?: React.Key }
118
- >(({ className, children, checked, ...props }, ref) => (
119
- <DropdownMenuPrimitive.CheckboxItem
120
- ref={ref}
121
- className={cn(
122
- "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
123
- className
124
- )}
125
- checked={checked}
126
- {...props}
127
- >
128
- <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
129
- <DropdownMenuPrimitive.ItemIndicator>
130
- <Check className="h-4 w-4" />
131
- </DropdownMenuPrimitive.ItemIndicator>
132
- </span>
133
- {children}
134
- </DropdownMenuPrimitive.CheckboxItem>
135
- ))
136
- DropdownMenuCheckboxItem.displayName =
137
- DropdownMenuPrimitive.CheckboxItem.displayName
138
-
139
- const DropdownMenuRadioItem = React.forwardRef<
140
- React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
141
- React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem> & { key?: React.Key }
142
- >(({ className, children, ...props }, ref) => (
143
- <DropdownMenuPrimitive.RadioItem
144
- ref={ref}
145
- className={cn(
146
- "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
147
- className
148
- )}
149
- {...props}
150
- >
151
- <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
152
- <DropdownMenuPrimitive.ItemIndicator>
153
- <Circle className="h-2 w-2 fill-current" />
154
- </DropdownMenuPrimitive.ItemIndicator>
155
- </span>
156
- {children}
157
- </DropdownMenuPrimitive.RadioItem>
158
- ))
159
- DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName
160
-
161
- const DropdownMenuLabel = React.forwardRef<
162
- React.ElementRef<typeof DropdownMenuPrimitive.Label>,
163
- React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
164
- inset?: boolean
165
- }
166
- >(({ className, inset, ...props }, ref) => (
167
- <DropdownMenuPrimitive.Label
168
- ref={ref}
169
- className={cn(
170
- "px-2 py-1.5 text-sm font-semibold",
171
- inset && "pl-8",
172
- className
173
- )}
174
- {...props}
175
- />
176
- ))
177
- DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName
178
-
179
- const DropdownMenuSeparator = React.forwardRef<
180
- React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
181
- React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
182
- >(({ className, ...props }, ref) => (
183
- <DropdownMenuPrimitive.Separator
184
- ref={ref}
185
- className={cn("-mx-1 my-1 h-px bg-muted", className)}
186
- {...props}
187
- />
188
- ))
189
- DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName
190
-
191
- const DropdownMenuShortcut = ({
192
- className,
193
- ...props
194
- }: React.HTMLAttributes<HTMLSpanElement>) => {
195
- return (
196
- <span
197
- className={cn("ml-auto text-xs tracking-widest opacity-60", className)}
198
- {...props}
199
- />
200
- )
201
- }
202
- DropdownMenuShortcut.displayName = "DropdownMenuShortcut"
203
-
204
- export {
205
- DropdownMenu,
206
- DropdownMenuTrigger,
207
- DropdownMenuContent,
208
- DropdownMenuItem,
209
- DropdownMenuCheckboxItem,
210
- DropdownMenuRadioItem,
211
- DropdownMenuLabel,
212
- DropdownMenuSeparator,
213
- DropdownMenuShortcut,
214
- DropdownMenuGroup,
215
- DropdownMenuPortal,
216
- DropdownMenuSub,
217
- DropdownMenuSubContent,
218
- DropdownMenuSubTrigger,
219
- DropdownMenuRadioGroup,
220
- }
@@ -1,52 +0,0 @@
1
- // ============================================================================
2
- // Next.js specific components (use next/link, next/image, etc.)
3
- // Re-exports base components from @djangocfg/ui-core for convenience
4
- // ============================================================================
5
-
6
- 'use client';
7
-
8
- // Re-export all base components from ui-core
9
- // (includes Link / ButtonLink — wired to next/link via NextLinkProvider in BaseApp)
10
- export * from '@djangocfg/ui-core/components';
11
-
12
- // Navigation Components (Next.js)
13
- export { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, BreadcrumbEllipsis } from './breadcrumb';
14
- export { BreadcrumbNavigation } from './breadcrumb-navigation';
15
- export type { BreadcrumbItem as BreadcrumbNavigationItem, BreadcrumbNavigationProps } from './breadcrumb-navigation';
16
-
17
- // Interactive Components (Next.js)
18
- export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from './dropdown-menu';
19
-
20
- // Pagination (Next.js)
21
- export { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious } from './pagination';
22
- export { SSRPagination } from './ssr-pagination';
23
- export { StaticPagination, useDRFPaginationInfo, useDRFPagination } from './pagination-static';
24
- export type { DRFPaginatedResponse } from './pagination-static';
25
-
26
- // Sidebar (Next.js)
27
- export {
28
- Sidebar,
29
- SidebarContent,
30
- SidebarFooter,
31
- SidebarGroup,
32
- SidebarGroupAction,
33
- SidebarGroupContent,
34
- SidebarGroupLabel,
35
- SidebarHeader,
36
- SidebarInput,
37
- SidebarInset,
38
- SidebarMenu,
39
- SidebarMenuAction,
40
- SidebarMenuBadge,
41
- SidebarMenuButton,
42
- SidebarMenuItem,
43
- SidebarMenuSkeleton,
44
- SidebarMenuSub,
45
- SidebarMenuSubButton,
46
- SidebarMenuSubItem,
47
- SidebarProvider,
48
- SidebarRail,
49
- SidebarSeparator,
50
- SidebarTrigger,
51
- useSidebar,
52
- } from './sidebar';