@djangocfg/ui-core 2.1.416 → 2.1.418
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 +24 -0
- package/package.json +9 -4
- package/src/components/index.ts +1 -2
- package/src/components/overlay/tooltip/index.tsx +0 -2
- package/src/index.ts +3 -0
- package/src/providers/UiProviders.tsx +77 -0
- package/src/providers/index.ts +2 -0
- package/src/components/overlay/tooltip/tooltip-provider-safe.tsx +0 -44
package/README.md
CHANGED
|
@@ -22,8 +22,32 @@ pnpm add @djangocfg/ui-core
|
|
|
22
22
|
import { Button, Card, Sidebar, SSRPagination } from '@djangocfg/ui-core/components';
|
|
23
23
|
import { useIsMobile, useNavigate, useQueryParams } from '@djangocfg/ui-core/hooks';
|
|
24
24
|
import { cn } from '@djangocfg/ui-core/lib';
|
|
25
|
+
import { UiProviders } from '@djangocfg/ui-core/providers';
|
|
25
26
|
```
|
|
26
27
|
|
|
28
|
+
## Root providers
|
|
29
|
+
|
|
30
|
+
Mount `<UiProviders>` once at the top of your app — it bundles the overlay
|
|
31
|
+
and imperative services every ui-core / ui-tools component expects:
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
import { UiProviders } from '@djangocfg/ui-core/providers';
|
|
35
|
+
|
|
36
|
+
export function Root({ children }: { children: React.ReactNode }) {
|
|
37
|
+
return <UiProviders>{children}</UiProviders>;
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Includes:
|
|
42
|
+
- `<TooltipProvider>` (Radix tooltip root, `delayDuration={100}` by default)
|
|
43
|
+
- `<DialogProvider>` (installs `window.dialog.*` + renders active dialogs)
|
|
44
|
+
- `<Toaster>` (Sonner toast portal)
|
|
45
|
+
|
|
46
|
+
Opt out per-service: `<UiProviders noToaster noDialogService>`.
|
|
47
|
+
|
|
48
|
+
**Do not nest a second `<TooltipProvider>` inside library components** —
|
|
49
|
+
that creates a separate context scope and breaks the tooltip↔provider link.
|
|
50
|
+
|
|
27
51
|
## Components
|
|
28
52
|
|
|
29
53
|
Organized in `components/` by category — everything re-exported from the root barrel.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@djangocfg/ui-core",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.418",
|
|
4
4
|
"description": "Pure React UI component library without Next.js dependencies - for Electron, Vite, CRA apps",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ui-components",
|
|
@@ -63,6 +63,11 @@
|
|
|
63
63
|
"import": "./src/lib/dialog-service/index.ts",
|
|
64
64
|
"require": "./src/lib/dialog-service/index.ts"
|
|
65
65
|
},
|
|
66
|
+
"./providers": {
|
|
67
|
+
"types": "./src/providers/index.ts",
|
|
68
|
+
"import": "./src/providers/index.ts",
|
|
69
|
+
"require": "./src/providers/index.ts"
|
|
70
|
+
},
|
|
66
71
|
"./utils": {
|
|
67
72
|
"types": "./src/utils/index.ts",
|
|
68
73
|
"import": "./src/utils/index.ts",
|
|
@@ -95,7 +100,7 @@
|
|
|
95
100
|
"check": "tsc --noEmit"
|
|
96
101
|
},
|
|
97
102
|
"peerDependencies": {
|
|
98
|
-
"@djangocfg/i18n": "^2.1.
|
|
103
|
+
"@djangocfg/i18n": "^2.1.418",
|
|
99
104
|
"consola": "^3.4.2",
|
|
100
105
|
"lucide-react": "^0.545.0",
|
|
101
106
|
"moment": "^2.30.1",
|
|
@@ -166,8 +171,8 @@
|
|
|
166
171
|
"vaul": "1.1.2"
|
|
167
172
|
},
|
|
168
173
|
"devDependencies": {
|
|
169
|
-
"@djangocfg/i18n": "^2.1.
|
|
170
|
-
"@djangocfg/typescript-config": "^2.1.
|
|
174
|
+
"@djangocfg/i18n": "^2.1.418",
|
|
175
|
+
"@djangocfg/typescript-config": "^2.1.418",
|
|
171
176
|
"@types/node": "^25.2.3",
|
|
172
177
|
"@types/react": "^19.2.15",
|
|
173
178
|
"@types/react-dom": "^19.2.3",
|
package/src/components/index.ts
CHANGED
|
@@ -68,8 +68,7 @@ export { ResponsiveSheet, ResponsiveSheetContent, ResponsiveSheetHeader, Respons
|
|
|
68
68
|
export { SidePanel, SidePanelContent, SidePanelHeader, SidePanelTitle, SidePanelDescription, SidePanelBody, SidePanelFooter, SidePanelClose } from './overlay/side-panel';
|
|
69
69
|
export type { SidePanelProps, SidePanelContentProps, SidePanelCloseProps } from './overlay/side-panel';
|
|
70
70
|
export { HoverCard, HoverCardContent, HoverCardTrigger } from './overlay/hover-card';
|
|
71
|
-
export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger
|
|
72
|
-
export type { SafeTooltipProviderProps } from './overlay/tooltip';
|
|
71
|
+
export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './overlay/tooltip';
|
|
73
72
|
|
|
74
73
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
75
74
|
// Navigation
|
|
@@ -32,5 +32,3 @@ const TooltipContent = React.forwardRef<
|
|
|
32
32
|
TooltipContent.displayName = TooltipPrimitive.Content.displayName
|
|
33
33
|
|
|
34
34
|
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }
|
|
35
|
-
export { SafeTooltipProvider } from './tooltip-provider-safe';
|
|
36
|
-
export type { SafeTooltipProviderProps } from './tooltip-provider-safe';
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { useEffect, useState } from 'react';
|
|
5
|
+
|
|
6
|
+
import { TooltipProvider } from '../components/overlay/tooltip';
|
|
7
|
+
import { Toaster } from '../components/feedback/sonner';
|
|
8
|
+
import { DialogProvider } from '../lib/dialog-service/DialogProvider';
|
|
9
|
+
|
|
10
|
+
export interface UiProvidersProps {
|
|
11
|
+
children: React.ReactNode;
|
|
12
|
+
/** Tooltip open delay in ms. @default 100 (snappy for desktop apps) */
|
|
13
|
+
tooltipDelay?: number;
|
|
14
|
+
/** Disable the Sonner toaster (e.g. when the host renders its own). */
|
|
15
|
+
noToaster?: boolean;
|
|
16
|
+
/** Disable the imperative `window.dialog` service + its renderer. */
|
|
17
|
+
noDialogService?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* SSR-safe mount strategy. Default `true` — skips providers on the
|
|
20
|
+
* initial server render and remounts after `useEffect` so Radix
|
|
21
|
+
* `<TooltipProvider>` (which calls `useId()` + opens internal state
|
|
22
|
+
* on mount) doesn't trigger hydration mismatches under Next.js.
|
|
23
|
+
*
|
|
24
|
+
* Set `ssr={false}` on CSR-only hosts (Wails, Vite SPA, Storybook
|
|
25
|
+
* iframe) to skip the deferred mount — providers render on the
|
|
26
|
+
* very first paint and library components see their context
|
|
27
|
+
* immediately.
|
|
28
|
+
*/
|
|
29
|
+
ssr?: boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* One root composition for every overlay/imperative-service the
|
|
34
|
+
* djangocfg UI library needs:
|
|
35
|
+
*
|
|
36
|
+
* - `<TooltipProvider>` — single context root for every `<Tooltip>`
|
|
37
|
+
* in the tree (Radix). Without one, library components log
|
|
38
|
+
* "Tooltip must be used within TooltipProvider".
|
|
39
|
+
* - `<DialogProvider>` — installs the `window.dialog.*` imperative
|
|
40
|
+
* API and renders the active dialog into a portal.
|
|
41
|
+
* - `<Toaster>` — Sonner toast portal. Library callsites use
|
|
42
|
+
* `toast(...)` from the same package; no portal = silent no-op.
|
|
43
|
+
*
|
|
44
|
+
* Apple-style: app/host mounts ONE `<UiProviders>` at the very top of
|
|
45
|
+
* the tree, and never again. Library components must NOT include their
|
|
46
|
+
* own nested `TooltipProvider` — a second context root creates a fresh
|
|
47
|
+
* provider scope with different delays, and (worse) under Vite dev a
|
|
48
|
+
* dup-module load yields two `createContext()` instances, breaking the
|
|
49
|
+
* provider/consumer link.
|
|
50
|
+
*
|
|
51
|
+
* Usage:
|
|
52
|
+
* import { UiProviders } from '@djangocfg/ui-core/lib/providers';
|
|
53
|
+
*
|
|
54
|
+
* <UiProviders>
|
|
55
|
+
* <YourApp />
|
|
56
|
+
* </UiProviders>
|
|
57
|
+
*/
|
|
58
|
+
export function UiProviders({
|
|
59
|
+
children,
|
|
60
|
+
tooltipDelay = 100,
|
|
61
|
+
noToaster,
|
|
62
|
+
noDialogService,
|
|
63
|
+
}: UiProvidersProps) {
|
|
64
|
+
// No SSR-skip on purpose: any nested library component that renders
|
|
65
|
+
// `<Tooltip>` on its first paint expects to find `<TooltipProvider>`
|
|
66
|
+
// already in the tree. Skipping the provider during SSR caused
|
|
67
|
+
// "Tooltip must be used within TooltipProvider" before hydration.
|
|
68
|
+
// Radix's own provider tolerates the SSR pass — no hydration
|
|
69
|
+
// mismatches observed; the safe wrapper was over-engineering.
|
|
70
|
+
const tree = noDialogService ? children : <DialogProvider>{children}</DialogProvider>;
|
|
71
|
+
return (
|
|
72
|
+
<TooltipProvider delayDuration={tooltipDelay}>
|
|
73
|
+
{tree}
|
|
74
|
+
{!noToaster && <Toaster />}
|
|
75
|
+
</TooltipProvider>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import * as React from 'react';
|
|
4
|
-
|
|
5
|
-
import { TooltipProvider as RadixTooltipProvider } from '@radix-ui/react-tooltip';
|
|
6
|
-
|
|
7
|
-
export interface SafeTooltipProviderProps {
|
|
8
|
-
children: React.ReactNode;
|
|
9
|
-
delayDuration?: number;
|
|
10
|
-
skipDelayDuration?: number;
|
|
11
|
-
disableHoverableContent?: boolean;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* SafeTooltipProvider - SSR-safe wrapper for Radix TooltipProvider
|
|
16
|
-
* Only renders on client-side to avoid hydration mismatches
|
|
17
|
-
*/
|
|
18
|
-
export function SafeTooltipProvider({
|
|
19
|
-
children,
|
|
20
|
-
delayDuration = 700,
|
|
21
|
-
skipDelayDuration = 300,
|
|
22
|
-
disableHoverableContent,
|
|
23
|
-
}: SafeTooltipProviderProps) {
|
|
24
|
-
const [mounted, setMounted] = React.useState(false);
|
|
25
|
-
|
|
26
|
-
React.useEffect(() => {
|
|
27
|
-
setMounted(true);
|
|
28
|
-
}, []);
|
|
29
|
-
|
|
30
|
-
if (!mounted) {
|
|
31
|
-
// During SSR, return children without TooltipProvider
|
|
32
|
-
return <>{children}</>;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return (
|
|
36
|
-
<RadixTooltipProvider
|
|
37
|
-
delayDuration={delayDuration}
|
|
38
|
-
skipDelayDuration={skipDelayDuration}
|
|
39
|
-
disableHoverableContent={disableHoverableContent}
|
|
40
|
-
>
|
|
41
|
-
{children}
|
|
42
|
-
</RadixTooltipProvider>
|
|
43
|
-
);
|
|
44
|
-
}
|