@djangocfg/ui-nextjs 2.1.177 → 2.1.179

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 CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Next.js UI library extending `@djangocfg/ui-core` with 69+ components built on Radix UI + Tailwind CSS v4.
4
4
 
5
+ All navigation components are **locale-aware** via `next-intl` — links automatically include the locale prefix (e.g. `/ru/dashboard`).
6
+
5
7
  **Part of [DjangoCFG](https://djangocfg.com)** — modern Django framework for production-ready SaaS applications.
6
8
 
7
9
  **[Live Demo & Props](https://djangocfg.com/demo/)**
@@ -12,12 +14,15 @@ Next.js UI library extending `@djangocfg/ui-core` with 69+ components built on R
12
14
  pnpm add @djangocfg/ui-nextjs
13
15
  ```
14
16
 
17
+ Peer dependencies: `next`, `next-intl`, `react`, `tailwindcss`.
18
+
15
19
  ## Architecture
16
20
 
17
21
  ```
18
22
  @djangocfg/ui-nextjs
19
23
  ├── Re-exports everything from @djangocfg/ui-core (60 components, 13 hooks)
20
- ├── + Next.js specific components (11)
24
+ ├── + Next.js locale-aware components (11)
25
+ ├── + Navigation hooks (useNavigation, useRouter, usePathname)
21
26
  ├── + Browser storage hooks (2)
22
27
  ├── + Blocks, Theme, Animations
23
28
  ```
@@ -25,7 +30,7 @@ pnpm add @djangocfg/ui-nextjs
25
30
  | Package | Use Case |
26
31
  |---------|----------|
27
32
  | `@djangocfg/ui-core` | Electron, Vite, CRA, any React app |
28
- | `@djangocfg/ui-nextjs` | Next.js apps (includes ui-core + extras) |
33
+ | `@djangocfg/ui-nextjs` | Next.js apps (includes ui-core + locale-aware navigation) |
29
34
 
30
35
  ## Components
31
36
 
@@ -34,25 +39,27 @@ All components from `@djangocfg/ui-core` are re-exported.
34
39
 
35
40
  ### Next.js Specific (11)
36
41
 
37
- | Component | Why Next.js |
42
+ | Component | Description |
38
43
  |-----------|-------------|
39
- | `NextLink` | Styled `next/link` wrapper |
40
- | `NextButtonLink` | Button-styled `next/link` with variants |
41
- | `Sidebar` | Uses `next/link` for navigation |
42
- | `Breadcrumb` | Uses `next/link` |
43
- | `BreadcrumbNavigation` | Uses `next/link` |
44
- | `NavigationMenu` | Uses `next/link` |
45
- | `Menubar` | Uses `next/link` |
46
- | `DropdownMenu` | Uses `next/link` |
47
- | `Pagination` | Uses `next/link` |
48
- | `SSRPagination` | Uses `next/link` + server components |
44
+ | `NextLink` | Locale-aware link wrapper |
45
+ | `NextButtonLink` | Button-styled locale-aware link with variants |
46
+ | `Sidebar` | Locale-aware navigation sidebar |
47
+ | `Breadcrumb` | Locale-aware breadcrumbs |
48
+ | `BreadcrumbNavigation` | High-level breadcrumb component |
49
+ | `NavigationMenu` | Locale-aware navigation menu |
50
+ | `Menubar` | Locale-aware menubar |
51
+ | `DropdownMenu` | Menu with locale-aware link items |
52
+ | `Pagination` | Locale-aware page links |
53
+ | `SSRPagination` | Server-compatible pagination |
49
54
  | `DownloadButton` | Uses `localStorage` for auth |
50
55
 
56
+ All link-based components use `next-intl` internally — no configuration needed.
57
+
51
58
  ### MultiSelect Pro
52
59
  `MultiSelectPro` `MultiSelectProAsync` — Advanced multi-select with async loading
53
60
 
54
61
  ### Blocks (7)
55
- `Hero` `SuperHero` `FeatureSection` `CTASection` `NewsletterSection` `StatsSection` `TestimonialSection`
62
+ `Hero` `SuperHero` `SplitHero` `ArticleCard` `FeatureSection` `CTASection` `StatsSection`
56
63
 
57
64
  ```tsx
58
65
  import { Hero } from '@djangocfg/ui-nextjs/blocks';
@@ -60,6 +67,24 @@ import { Hero } from '@djangocfg/ui-nextjs/blocks';
60
67
 
61
68
  ## Hooks
62
69
 
70
+ ### Navigation (locale-aware)
71
+
72
+ | Hook | Description |
73
+ |------|-------------|
74
+ | `useNavigation` | Returns `{ router, pathname, redirect }` — all locale-aware |
75
+ | `useRouter` | Locale-aware router (`router.push('/page')` → `/ru/page`) |
76
+ | `usePathname` | Current pathname without locale prefix |
77
+
78
+ ```tsx
79
+ import { useNavigation } from '@djangocfg/ui-nextjs/hooks';
80
+
81
+ function MyComponent() {
82
+ const { router, pathname } = useNavigation();
83
+ // pathname: "/dashboard" (not "/ru/dashboard")
84
+ // router.push('/settings') → navigates to /ru/settings
85
+ }
86
+ ```
87
+
63
88
  ### From ui-core (13)
64
89
 
65
90
  | Hook | Description |
@@ -78,14 +103,13 @@ import { Hero } from '@djangocfg/ui-nextjs/blocks';
78
103
  | `useBrowserDetect` | Browser detection |
79
104
  | `useDeviceDetect` | Device detection |
80
105
 
81
- ### Next.js Specific (2)
106
+ ### Next.js Specific (3)
82
107
 
83
108
  | Hook | Description |
84
109
  |------|-------------|
85
110
  | `useResolvedTheme` | Light/dark theme resolution (next-themes) |
86
111
  | `useLocalStorage` | Persistent state in localStorage |
87
-
88
- Note: `useSessionStorage` is also available in ui-core.
112
+ | `useSessionStorage` | Persistent state in sessionStorage |
89
113
 
90
114
  ## Dialog Service
91
115
 
@@ -102,20 +126,23 @@ See ui-core README for full documentation.
102
126
  ```tsx
103
127
  import {
104
128
  Button, Card, Input, // from ui-core
105
- NextButtonLink, Sidebar // Next.js specific
129
+ NextButtonLink, Sidebar // Next.js locale-aware
106
130
  } from '@djangocfg/ui-nextjs';
107
- import { useLocalStorage } from '@djangocfg/ui-nextjs/hooks';
131
+ import { useNavigation, useLocalStorage } from '@djangocfg/ui-nextjs/hooks';
108
132
 
109
133
  function Example() {
134
+ const { router, pathname } = useNavigation();
110
135
  const [saved, setSaved] = useLocalStorage('form', null);
111
136
 
112
137
  return (
113
138
  <Sidebar>
114
139
  <Card>
115
140
  <Input placeholder="Email" />
116
- <Button>Submit</Button>
117
- <NextButtonLink href="/dashboard" variant="outline">
118
- Go to Dashboard
141
+ <Button onClick={() => router.push('/dashboard')}>
142
+ Submit
143
+ </Button>
144
+ <NextButtonLink href="/docs" variant="outline">
145
+ Documentation
119
146
  </NextButtonLink>
120
147
  </Card>
121
148
  </Sidebar>
@@ -129,7 +156,7 @@ function Example() {
129
156
  import { NextButtonLink } from '@djangocfg/ui-nextjs';
130
157
  import { ArrowLeft, Settings } from 'lucide-react';
131
158
 
132
- // Basic
159
+ // Basic — automatically gets locale prefix
133
160
  <NextButtonLink href="/dashboard">Dashboard</NextButtonLink>
134
161
 
135
162
  // With variants
@@ -147,6 +174,11 @@ import { ArrowLeft, Settings } from 'lucide-react';
147
174
  <NextButtonLink href="/page" prefetch={false} replace scroll={false}>
148
175
  Navigate
149
176
  </NextButtonLink>
177
+
178
+ // With locale override
179
+ <NextButtonLink href="/docs" locale="en">
180
+ English Docs
181
+ </NextButtonLink>
150
182
  ```
151
183
 
152
184
  ## Styling
@@ -185,6 +217,7 @@ mediaLog.buffer(buffered, duration);
185
217
  | `@djangocfg/ui-nextjs/blocks` | Landing page blocks |
186
218
  | `@djangocfg/ui-nextjs/lib` | Logger, utilities |
187
219
  | `@djangocfg/ui-nextjs/theme` | ThemeProvider, ThemeToggle |
220
+ | `@djangocfg/ui-nextjs/animations` | Background animations |
188
221
  | `@djangocfg/ui-nextjs/styles` | CSS |
189
222
 
190
223
  ## Theme
@@ -210,9 +243,10 @@ function App({ children }) {
210
243
 
211
244
  ## Requirements
212
245
 
213
- - Next.js >= 15
246
+ - Next.js >= 16
214
247
  - React >= 19
215
248
  - Tailwind CSS >= 4
249
+ - next-intl >= 4
216
250
 
217
251
  ---
218
252
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@djangocfg/ui-nextjs",
3
- "version": "2.1.177",
3
+ "version": "2.1.179",
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",
@@ -80,15 +80,16 @@
80
80
  "check": "tsc --noEmit"
81
81
  },
82
82
  "peerDependencies": {
83
- "@djangocfg/api": "^2.1.177",
84
- "@djangocfg/ui-core": "^2.1.177",
85
- "@djangocfg/ui-tools": "^2.1.177",
83
+ "@djangocfg/api": "^2.1.179",
84
+ "@djangocfg/ui-core": "^2.1.179",
85
+ "@djangocfg/ui-tools": "^2.1.179",
86
86
  "@types/react": "^19.1.0",
87
87
  "@types/react-dom": "^19.1.0",
88
88
  "consola": "^3.4.2",
89
89
  "lucide-react": "^0.545.0",
90
90
  "moment": "^2.30.1",
91
91
  "next": "^16.0.10",
92
+ "next-intl": "^4.8.3",
92
93
  "react": "^19.1.0",
93
94
  "react-dom": "^19.1.0",
94
95
  "react-hook-form": "^7.69.0",
@@ -104,13 +105,14 @@
104
105
  "react-chartjs-2": "^5.3.0"
105
106
  },
106
107
  "devDependencies": {
107
- "@djangocfg/typescript-config": "^2.1.177",
108
+ "@djangocfg/typescript-config": "^2.1.179",
108
109
  "@radix-ui/react-dropdown-menu": "^2.1.16",
109
110
  "@radix-ui/react-slot": "^1.2.4",
110
111
  "@types/node": "^24.7.2",
111
112
  "class-variance-authority": "^0.7.1",
112
113
  "eslint": "^9.37.0",
113
114
  "tailwindcss-animate": "1.0.7",
115
+ "next-intl": "^4.8.3",
114
116
  "typescript": "^5.9.3",
115
117
  "zustand": "^5.0.9"
116
118
  },
@@ -2,8 +2,10 @@ import React from 'react';
2
2
  import moment from 'moment';
3
3
 
4
4
  import {
5
- Badge, ButtonLink, Card, CardContent, CardDescription, CardHeader, CardTitle
5
+ Badge, Card, CardContent, CardDescription, CardHeader, CardTitle
6
6
  } from '@djangocfg/ui-core/components';
7
+
8
+ import { NextButtonLink as ButtonLink } from '../components/next-link';
7
9
  import { cn } from '@djangocfg/ui-core/lib';
8
10
 
9
11
  export type ArticleType = 'security' | 'release' | 'announcement' | 'feature';
@@ -1,8 +1,9 @@
1
1
  import React from 'react';
2
2
 
3
- import { ButtonLink } from '@djangocfg/ui-core/components';
4
3
  import { cn } from '@djangocfg/ui-core/lib';
5
4
 
5
+ import { NextButtonLink as ButtonLink } from '../components/next-link';
6
+
6
7
  interface HeroProps {
7
8
  title: string;
8
9
  subtitle?: string;
@@ -2,8 +2,9 @@
2
2
 
3
3
  import React from 'react';
4
4
  import { ArrowRight, Sparkles } from 'lucide-react';
5
- import { ButtonLink } from '@djangocfg/ui-core/components';
6
5
  import { cn } from '@djangocfg/ui-core/lib';
6
+
7
+ import { NextButtonLink as ButtonLink } from '../../components/next-link';
7
8
  import type { SplitHeroBadge, SplitHeroAction, SplitHeroFeature } from './types';
8
9
 
9
10
  interface SplitHeroContentProps {
@@ -4,8 +4,10 @@ import { ArrowRight, Sparkles, Wand2 } from 'lucide-react';
4
4
  import React from 'react';
5
5
 
6
6
  import {
7
- Button, ButtonLink, CopyButton, Sticky, Tooltip, TooltipContent, TooltipTrigger
7
+ Button, CopyButton, Sticky, Tooltip, TooltipContent, TooltipTrigger
8
8
  } from '@djangocfg/ui-core/components';
9
+
10
+ import { NextButtonLink as ButtonLink } from '../components/next-link';
9
11
  import { cn } from '@djangocfg/ui-core/lib';
10
12
 
11
13
  import { AnimatedBackground, BackgroundVariant} from '../animations';
@@ -1,4 +1,4 @@
1
- import Link from 'next/link';
1
+ import { Link } from '../lib/navigation';
2
2
  import React from 'react';
3
3
 
4
4
  // cn is available for future use
@@ -1,7 +1,7 @@
1
1
  "use client"
2
2
 
3
3
  import { ChevronRight, MoreHorizontal } from 'lucide-react';
4
- import Link from 'next/link';
4
+ import { Link } from '../lib/navigation';
5
5
  import * as React from 'react';
6
6
 
7
7
  import { cn } from '@djangocfg/ui-core/lib';
@@ -1,7 +1,7 @@
1
1
  "use client"
2
2
 
3
3
  import { Check, ChevronRight, Circle } from 'lucide-react';
4
- import Link from 'next/link';
4
+ import { Link } from '../lib/navigation';
5
5
  import * as React from 'react';
6
6
 
7
7
  import { cn } from '@djangocfg/ui-core/lib';
@@ -1,19 +1,22 @@
1
1
  'use client';
2
2
 
3
3
  import * as React from 'react';
4
- import Link from 'next/link';
5
- import type { LinkProps } from 'next/link';
4
+ import type { LinkProps as NextLinkBaseProps } from 'next/link';
5
+ import { Link } from '../lib/navigation';
6
6
  import { buttonVariants } from '@djangocfg/ui-core/components';
7
7
  import type { VariantProps } from 'class-variance-authority';
8
8
  import { cn } from '@djangocfg/ui-core/lib';
9
9
 
10
+ type IntlLinkProps = React.ComponentProps<typeof Link>;
11
+
10
12
  // ============================================================================
11
13
  // NextLink - Styled Next.js Link (text link style)
12
14
  // ============================================================================
13
15
 
14
16
  export interface NextLinkProps
15
- extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, keyof LinkProps>,
16
- LinkProps {
17
+ extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, keyof NextLinkBaseProps>,
18
+ NextLinkBaseProps {
19
+ locale?: string;
17
20
  children?: React.ReactNode;
18
21
  }
19
22
 
@@ -29,7 +32,7 @@ export interface NextLinkProps
29
32
  const NextLink = React.forwardRef<HTMLAnchorElement, NextLinkProps>(
30
33
  ({ children, ...props }, ref) => {
31
34
  return (
32
- <Link ref={ref} {...props}>
35
+ <Link ref={ref} {...props as IntlLinkProps}>
33
36
  {children}
34
37
  </Link>
35
38
  );
@@ -42,9 +45,10 @@ NextLink.displayName = 'NextLink';
42
45
  // ============================================================================
43
46
 
44
47
  export interface NextButtonLinkProps
45
- extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, keyof LinkProps>,
46
- LinkProps,
48
+ extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, keyof NextLinkBaseProps>,
49
+ NextLinkBaseProps,
47
50
  VariantProps<typeof buttonVariants> {
51
+ locale?: string;
48
52
  children?: React.ReactNode;
49
53
  }
50
54
 
@@ -75,7 +79,7 @@ const NextButtonLink = React.forwardRef<HTMLAnchorElement, NextButtonLinkProps>(
75
79
  <Link
76
80
  className={cn(buttonVariants({ variant, size, className }))}
77
81
  ref={ref}
78
- {...props}
82
+ {...props as IntlLinkProps}
79
83
  >
80
84
  {children}
81
85
  </Link>
@@ -1,5 +1,5 @@
1
1
  import { ChevronLeft, ChevronRight, MoreHorizontal } from 'lucide-react';
2
- import Link from 'next/link';
2
+ import { Link } from '../lib/navigation';
3
3
  import * as React from 'react';
4
4
 
5
5
  import { ButtonProps, buttonVariants} from '@djangocfg/ui-core/components';
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { cva, VariantProps } from 'class-variance-authority';
4
4
  import { PanelLeft } from 'lucide-react';
5
- import Link from 'next/link';
5
+ import { Link } from '../lib/navigation';
6
6
  import * as React from 'react';
7
7
 
8
8
  import {
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
 
3
- import { usePathname } from 'next/navigation';
3
+ import { usePathname } from '../lib/navigation';
4
4
  import React from 'react';
5
5
 
6
6
  import { useIsMobile } from '@djangocfg/ui-core/hooks';
@@ -5,6 +5,10 @@
5
5
 
6
6
  'use client';
7
7
 
8
+ // Locale-aware navigation hooks (next-intl)
9
+ export { useRouter, usePathname } from '../lib/navigation';
10
+ export { useNavigation } from './useNavigation';
11
+
8
12
  // Theme hook (standalone, no provider required)
9
13
  export { useResolvedTheme } from './useResolvedTheme';
10
14
  export type { ResolvedTheme } from './useResolvedTheme';
@@ -0,0 +1,20 @@
1
+ 'use client';
2
+
3
+ import { useRouter, usePathname, redirect } from '../lib/navigation';
4
+
5
+ /**
6
+ * Locale-aware navigation hook.
7
+ *
8
+ * Returns router, pathname (without locale prefix), and redirect —
9
+ * all automatically scoped to the current locale.
10
+ *
11
+ * @example
12
+ * const { router, pathname } = useNavigation();
13
+ * router.push('/dashboard'); // → /ru/dashboard when locale is "ru"
14
+ */
15
+ export function useNavigation() {
16
+ const router = useRouter();
17
+ const pathname = usePathname();
18
+
19
+ return { router, pathname, redirect };
20
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Internal navigation utilities for ui-nextjs
3
+ *
4
+ * Uses next-intl's createNavigation() to produce locale-aware
5
+ * Link, usePathname, useRouter, etc.
6
+ *
7
+ * These are used internally by ui-nextjs components (breadcrumb, pagination, sidebar, etc.)
8
+ * so that all links automatically include the locale prefix.
9
+ */
10
+ import { createNavigation } from 'next-intl/navigation';
11
+
12
+ export const {
13
+ Link,
14
+ usePathname,
15
+ useRouter,
16
+ redirect,
17
+ } = createNavigation();