@donotdev/ui 0.0.7 → 0.0.8
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/assets/fonts/fonts.css +4 -4
- package/dist/components/auth/AuthHeader.d.ts +5 -0
- package/dist/components/auth/AuthHeader.d.ts.map +1 -1
- package/dist/components/auth/AuthHeader.js +22 -8
- package/dist/components/auth/AuthMenu.d.ts +6 -2
- package/dist/components/auth/AuthMenu.d.ts.map +1 -1
- package/dist/components/auth/AuthMenu.js +2 -2
- package/dist/components/common/RedirectOverlay.d.ts +37 -0
- package/dist/components/common/RedirectOverlay.d.ts.map +1 -0
- package/dist/components/common/RedirectOverlay.js +243 -0
- package/dist/components/common/index.d.ts +1 -0
- package/dist/components/common/index.d.ts.map +1 -1
- package/dist/components/common/index.js +1 -0
- package/dist/components/layout/components/header/SettingsMenu.d.ts.map +1 -1
- package/dist/components/layout/components/header/SettingsMenu.js +1 -1
- package/dist/crud/components/DisplayFieldRenderer.js +1 -1
- package/dist/dndev.css +447 -63
- package/dist/index.js +4 -4
- package/dist/internal/devtools/components/DesignTab.d.ts.map +1 -1
- package/dist/internal/devtools/components/DesignTab.js +25 -3
- package/dist/internal/layout/components/PerformanceHints.d.ts.map +1 -1
- package/dist/internal/layout/components/PerformanceHints.js +3 -2
- package/dist/internal/layout/config/presets/admin.d.ts +2 -2
- package/dist/internal/layout/config/presets/admin.d.ts.map +1 -1
- package/dist/internal/layout/config/presets/admin.js +8 -4
- package/dist/providers/NextJsAppProviders.d.ts.map +1 -1
- package/dist/providers/NextJsAppProviders.js +4 -1
- package/dist/routing/hooks/hooks.next.d.ts +1 -0
- package/dist/routing/hooks/hooks.next.d.ts.map +1 -1
- package/dist/routing/hooks/hooks.next.js +1 -1
- package/dist/routing/hooks/hooks.vite.d.ts +1 -0
- package/dist/routing/hooks/hooks.vite.d.ts.map +1 -1
- package/dist/routing/hooks/hooks.vite.js +1 -1
- package/dist/routing/hooks/useRouteParam.next.d.ts +18 -0
- package/dist/routing/hooks/useRouteParam.next.d.ts.map +1 -0
- package/dist/routing/hooks/useRouteParam.next.js +38 -0
- package/dist/routing/hooks/useRouteParam.vite.d.ts +18 -0
- package/dist/routing/hooks/useRouteParam.vite.d.ts.map +1 -0
- package/dist/routing/hooks/useRouteParam.vite.js +38 -0
- package/dist/routing/index.d.ts +1 -1
- package/dist/routing/index.d.ts.map +1 -1
- package/dist/routing/index.js +1 -1
- package/dist/styles/index.css +443 -59
- package/dist/utils/useCrudSafe.d.ts.map +1 -1
- package/dist/utils/useCrudSafe.js +2 -1
- package/dist/vite-routing/RootLayout.d.ts.map +1 -1
- package/dist/vite-routing/RootLayout.js +4 -1
- package/package.json +9 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DesignTab.d.ts","sourceRoot":"","sources":["../../../../src/internal/devtools/components/DesignTab.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"DesignTab.d.ts","sourceRoot":"","sources":["../../../../src/internal/devtools/components/DesignTab.tsx"],"names":[],"mappings":"AA+CA,eAAO,MAAM,SAAS,+CA2yBrB,CAAC"}
|
|
@@ -175,6 +175,9 @@ export const DesignTab = () => {
|
|
|
175
175
|
'--input',
|
|
176
176
|
'--ring',
|
|
177
177
|
'--radius',
|
|
178
|
+
'--font-sans',
|
|
179
|
+
'--font-mono',
|
|
180
|
+
'--font-family',
|
|
178
181
|
];
|
|
179
182
|
relevantVars.forEach((varName) => {
|
|
180
183
|
const value = style.getPropertyValue(varName).trim();
|
|
@@ -194,6 +197,7 @@ export const DesignTab = () => {
|
|
|
194
197
|
const analyzeTypography = () => {
|
|
195
198
|
const elements = document.querySelectorAll('*');
|
|
196
199
|
const fontSizeMap = new Map();
|
|
200
|
+
const fontFamilyMap = new Map();
|
|
197
201
|
let analyzedCount = 0;
|
|
198
202
|
elements.forEach((el) => {
|
|
199
203
|
if (isOverlayElement(el))
|
|
@@ -216,12 +220,23 @@ export const DesignTab = () => {
|
|
|
216
220
|
const fontSize = style.fontSize;
|
|
217
221
|
const fontSizeRounded = parseFloat(fontSize).toFixed(2) + 'px';
|
|
218
222
|
fontSizeMap.set(fontSizeRounded, (fontSizeMap.get(fontSizeRounded) || 0) + 1);
|
|
223
|
+
const fontFamily = style.fontFamily
|
|
224
|
+
?.split(',')[0]
|
|
225
|
+
?.trim()
|
|
226
|
+
?.replace(/['"]/g, '');
|
|
227
|
+
if (fontFamily) {
|
|
228
|
+
fontFamilyMap.set(fontFamily, (fontFamilyMap.get(fontFamily) || 0) + 1);
|
|
229
|
+
}
|
|
219
230
|
});
|
|
220
231
|
const fontSizes = Array.from(fontSizeMap.entries())
|
|
221
232
|
.map(([size, count]) => ({ size, count }))
|
|
222
233
|
.sort((a, b) => b.count - a.count);
|
|
234
|
+
const fontFamilies = Array.from(fontFamilyMap.entries())
|
|
235
|
+
.map(([family, count]) => ({ family, count }))
|
|
236
|
+
.sort((a, b) => b.count - a.count);
|
|
223
237
|
return {
|
|
224
238
|
fontSizes,
|
|
239
|
+
fontFamilies,
|
|
225
240
|
totalElements: analyzedCount,
|
|
226
241
|
};
|
|
227
242
|
};
|
|
@@ -376,7 +391,14 @@ export const DesignTab = () => {
|
|
|
376
391
|
flexShrink: 0,
|
|
377
392
|
} }), _jsxs(Text, { className: "dndev-text-xs dndev-font-mono", style: { flex: 1 }, children: [c.percentage.toFixed(1), "%"] }), _jsx(Badge, { variant: BADGE_VARIANT.SECONDARY, children: c.category })] }, i))) })),
|
|
378
393
|
},
|
|
379
|
-
] }))] }) })), typography && (
|
|
394
|
+
] }))] }) })), typography && typography.fontFamilies.length > 0 && (_jsx(Card, { content: _jsxs(Stack, { direction: "row", align: "center", justify: "between", className: "dndev-w-full", children: [_jsx("span", { children: "Font Families" }), _jsxs(Badge, { variant: BADGE_VARIANT.SECONDARY, children: [typography.fontFamilies.length, " families"] })] }), children: _jsx(Stack, { gap: "tight", className: "dndev-mt-xs", children: typography.fontFamilies.map((f, i) => (_jsxs(Stack, { direction: "row", justify: "between", align: "center", gap: "tight", style: {
|
|
395
|
+
padding: 'var(--gap-sm)',
|
|
396
|
+
borderRadius: 'var(--radius-sm)',
|
|
397
|
+
}, children: [_jsx(Text, { className: "dndev-font-mono dndev-text-xs", style: { flex: 1 }, children: f.family }), _jsxs(Text, { className: "dndev-text-xs", style: {
|
|
398
|
+
opacity: 0.6,
|
|
399
|
+
minWidth: '2rem',
|
|
400
|
+
textAlign: 'end',
|
|
401
|
+
}, children: [f.count, "\u00D7"] })] }, i))) }) })), typography && (_jsxs(Card, { content: _jsxs(Stack, { direction: "row", align: "center", justify: "between", className: "dndev-w-full", children: [_jsx("span", { children: "Font Sizes" }), _jsxs(Badge, { variant: BADGE_VARIANT.SECONDARY, children: [typography.totalElements, " elements"] })] }), children: [_jsxs(Stack, { direction: "row", align: "center", justify: "between", children: [_jsxs(Label, { className: "dndev-text-sm dndev-font-semibold", children: [typography.fontSizes.length, " sizes"] }), (highlightedSize || Object.keys(fontSizeColors).length > 0) && (_jsx(Button, { variant: BUTTON_VARIANT.GHOST, onClick: clearHighlights, style: { padding: '0 var(--gap-sm)', height: 'auto' }, children: _jsx(Text, { className: "dndev-text-xs", children: "Clear All" }) }))] }), _jsx(Stack, { gap: "tight", className: "dndev-mt-xs", children: typography.fontSizes.map((f, i) => {
|
|
380
402
|
const isOrphan = f.count < 5;
|
|
381
403
|
const isHighlighted = highlightedSize === f.size;
|
|
382
404
|
const currentColor = fontSizeColors[f.size] || '';
|
|
@@ -400,7 +422,7 @@ export const DesignTab = () => {
|
|
|
400
422
|
console.log(`Found ${found.length} elements with ${f.size}`);
|
|
401
423
|
};
|
|
402
424
|
return (_jsxs(Stack, { direction: "row", justify: "between", align: "center", gap: "tight", style: {
|
|
403
|
-
padding: 'var(--gap-
|
|
425
|
+
padding: 'var(--gap-sm)',
|
|
404
426
|
borderRadius: 'var(--radius-sm)',
|
|
405
427
|
backgroundColor: isHighlighted
|
|
406
428
|
? 'var(--primary)'
|
|
@@ -412,7 +434,7 @@ export const DesignTab = () => {
|
|
|
412
434
|
e.stopPropagation();
|
|
413
435
|
findOrphanElements();
|
|
414
436
|
}, style: {
|
|
415
|
-
padding: '0 var(--gap-
|
|
437
|
+
padding: '0 var(--gap-sm)',
|
|
416
438
|
height: '1.5rem',
|
|
417
439
|
minWidth: '2rem',
|
|
418
440
|
}, title: `Find ${f.size} elements in console`, children: _jsx(Text, { className: "dndev-text-xs", children: "\uD83D\uDD0D" }) })) : (_jsx("input", { type: "color", value: currentColor || '#000000', onChange: (e) => applyFontSizeColor(f.size, e.target.value), onClick: (e) => e.stopPropagation(), style: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PerformanceHints.d.ts","sourceRoot":"","sources":["../../../../src/internal/layout/components/PerformanceHints.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"PerformanceHints.d.ts","sourceRoot":"","sources":["../../../../src/internal/layout/components/PerformanceHints.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAmC3C,UAAU,WAAW;IACnB,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,WAAW,CAAC,EAAE,WAAW,GAAG,iBAAiB,CAAC;CAC/C;AAED,UAAU,qBAAqB;IAC7B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB;;;;OAIG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,GAAG,WAAW,CAAC,EAAE,CAAC;IACxC;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,QAAA,MAAM,gBAAgB,EAAE,aAAa,CAAC,qBAAqB,CA6D1D,CAAC;AAEF,eAAe,gBAAgB,CAAC;AAChC,YAAY,EAAE,WAAW,EAAE,qBAAqB,EAAE,CAAC"}
|
|
@@ -40,9 +40,10 @@ const DEFAULT_DNS_PREFETCH = [
|
|
|
40
40
|
];
|
|
41
41
|
/**
|
|
42
42
|
* Default critical fonts to preload
|
|
43
|
-
*
|
|
43
|
+
* Empty by default - apps should specify their own fonts based on their font-display strategy
|
|
44
|
+
* Note: Don't preload fonts with font-display: optional (they're meant to be non-blocking)
|
|
44
45
|
*/
|
|
45
|
-
const DEFAULT_FONT_PRELOADS = [
|
|
46
|
+
const DEFAULT_FONT_PRELOADS = [];
|
|
46
47
|
/**
|
|
47
48
|
* PerformanceHints component
|
|
48
49
|
*
|
|
@@ -12,8 +12,8 @@ import type { PresetConfig } from '@donotdev/core';
|
|
|
12
12
|
* Admin preset - admin panel layout
|
|
13
13
|
*
|
|
14
14
|
* Zones:
|
|
15
|
-
* - Header: Logo + title (left),
|
|
16
|
-
* - Sidebar: Navigation menu
|
|
15
|
+
* - Header: Logo + title (left), GoTo + Auth + Language + Theme (right)
|
|
16
|
+
* - Sidebar: Navigation menu only (no bottom controls - they're in header)
|
|
17
17
|
* - Footer: Automatic footer (copyright + legal links + DoNotDev branding)
|
|
18
18
|
*
|
|
19
19
|
* Mobile behavior:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../../../../src/internal/layout/config/presets/admin.tsx"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../../../../src/internal/layout/config/presets/admin.tsx"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW,EAAE,YAkBzB,CAAC"}
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* Admin preset - admin panel layout
|
|
4
4
|
*
|
|
5
5
|
* Zones:
|
|
6
|
-
* - Header: Logo + title (left),
|
|
7
|
-
* - Sidebar: Navigation menu
|
|
6
|
+
* - Header: Logo + title (left), GoTo + Auth + Language + Theme (right)
|
|
7
|
+
* - Sidebar: Navigation menu only (no bottom controls - they're in header)
|
|
8
8
|
* - Footer: Automatic footer (copyright + legal links + DoNotDev branding)
|
|
9
9
|
*
|
|
10
10
|
* Mobile behavior:
|
|
@@ -13,8 +13,12 @@
|
|
|
13
13
|
*/
|
|
14
14
|
export const adminPreset = {
|
|
15
15
|
name: 'admin',
|
|
16
|
-
// header omitted → uses DEFAULT_SLOTS.header
|
|
17
|
-
|
|
16
|
+
// header omitted → uses DEFAULT_SLOTS.header (GoTo + Auth + Language + Theme)
|
|
17
|
+
sidebar: {
|
|
18
|
+
// content omitted → uses DEFAULT_SLOTS.sidebar.content (NavigationMenu)
|
|
19
|
+
// bottom explicitly empty - Auth/Language/Theme are in header, no duplication
|
|
20
|
+
bottom: () => null,
|
|
21
|
+
},
|
|
18
22
|
footer: {},
|
|
19
23
|
mobile: {
|
|
20
24
|
mergedBar: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NextJsAppProviders.d.ts","sourceRoot":"","sources":["../../src/providers/NextJsAppProviders.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"NextJsAppProviders.d.ts","sourceRoot":"","sources":["../../src/providers/NextJsAppProviders.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAuDxD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,WAAW,uBAAwB,SAAQ,iBAAiB;IAChE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,2CAiDhE"}
|
|
@@ -28,6 +28,9 @@ const PWAUpdateNotification = lazy(() => import('../internal/layout/components/P
|
|
|
28
28
|
const LicenseWatermark = lazy(() => import('../components/license/LicenseWatermark').then((m) => ({
|
|
29
29
|
default: m.LicenseWatermark,
|
|
30
30
|
})));
|
|
31
|
+
const RedirectOverlay = lazy(() => import('../components/common/RedirectOverlay').then((m) => ({
|
|
32
|
+
default: m.RedirectOverlay,
|
|
33
|
+
})));
|
|
31
34
|
/**
|
|
32
35
|
* ConsentBanner - Lazy loaded consent component
|
|
33
36
|
* Only shows if user hasn't consented yet
|
|
@@ -46,5 +49,5 @@ function ConsentBanner() {
|
|
|
46
49
|
}
|
|
47
50
|
export function NextJsAppProviders(props) {
|
|
48
51
|
const { config = {}, layout, children, serverCookies, customStores } = props;
|
|
49
|
-
return (_jsxs(AppConfigProvider, { config: config, platform: "nextjs", children: [_jsx(SentryInitializer, {}), _jsx(HelmetProvider, { children: _jsxs(NextJsStoresInitializer, { serverCookies: serverCookies, customStores: customStores, children: [_jsx(FaviconHead, {}), _jsx(PerformanceHints, {}), _jsx(QueryProviders, { children: _jsxs(UIProviders, { children: [_jsx(DnDevLayout, { layout: layout, children: children }), _jsx(ConsentBanner, {}), _jsx(Suspense, { fallback: null, children: _jsx(PWAUpdateNotification, {}) }), _jsx(Suspense, { fallback: null, children: _jsx(LicenseWatermark, {}) })] }) })] }) })] }));
|
|
52
|
+
return (_jsxs(AppConfigProvider, { config: config, platform: "nextjs", children: [_jsx(SentryInitializer, {}), _jsx(HelmetProvider, { children: _jsxs(NextJsStoresInitializer, { serverCookies: serverCookies, customStores: customStores, children: [_jsx(FaviconHead, {}), _jsx(PerformanceHints, {}), _jsx(QueryProviders, { children: _jsxs(UIProviders, { children: [_jsx(DnDevLayout, { layout: layout, children: children }), _jsx(ConsentBanner, {}), _jsx(Suspense, { fallback: null, children: _jsx(PWAUpdateNotification, {}) }), _jsx(Suspense, { fallback: null, children: _jsx(LicenseWatermark, {}) }), _jsx(Suspense, { fallback: null, children: _jsx(RedirectOverlay, {}) })] }) })] }) })] }));
|
|
50
53
|
}
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
export { useNavigate, useBack, useRefresh, usePrefetch, } from './useNavigate.next';
|
|
11
11
|
export { useLocation } from './useLocation.next';
|
|
12
12
|
export { useParams } from './useParams.next';
|
|
13
|
+
export { useRouteParam } from './useRouteParam.next';
|
|
13
14
|
export { useSearchParams } from './useSearchParams.next';
|
|
14
15
|
export { useMatch } from './useMatch.next';
|
|
15
16
|
export { useQueryParams } from './useQueryParams.next';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.next.d.ts","sourceRoot":"","sources":["../../../src/routing/hooks/hooks.next.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AAEH,OAAO,EACL,WAAW,EACX,OAAO,EACP,UAAU,EACV,WAAW,GACZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,YAAY,EACV,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"hooks.next.d.ts","sourceRoot":"","sources":["../../../src/routing/hooks/hooks.next.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AAEH,OAAO,EACL,WAAW,EACX,OAAO,EACP,UAAU,EACV,WAAW,GACZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,YAAY,EACV,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,yBAAyB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{useCallback as f}from"react";import{useRouter as h}from"next/navigation";import{isClient as
|
|
1
|
+
"use client";import{useCallback as f}from"react";import{useRouter as h}from"next/navigation";import{isClient as S,useOverlayStore as y}from"@donotdev/core";function d(){let e=h(),t=y(r=>r.closeAll);return f((r,i)=>{if(r==="back")return t(),e.back();if(t(),i?.preserveScroll&&S()){let o=window.scrollY;i?.replace?e.replace(r):e.push(r),requestAnimationFrame(()=>{window.scrollTo({top:o,behavior:"auto"})});return}return i?.replace?e.replace(r):e.push(r)},[e,t])}function k(){let e=h();return f(()=>e.back(),[e])}function v(){let e=h();return f(()=>e.refresh(),[e])}function T(){let e=h();return f(t=>e.prefetch(t),[e])}import{usePathname as b,useSearchParams as w}from"next/navigation";function l(){let e=b(),t=w(),r=t.toString()?`?${t.toString()}`:"";return{pathname:e||"/",search:r,hash:"",state:null}}import{useParams as C}from"next/navigation";function g(){return C()}function I(e){let r=g()[e];if(typeof r=="string")return r;if(Array.isArray(r)&&r.length>0)return r[0]}import{useSearchParams as N}from"next/navigation";function R(){return N()}import{usePathname as G}from"next/navigation";function $(e){let t=G(),r=e.replace(/:[^/]+/g,"([^/]+)").replace(/\*/g,".*"),i=new RegExp(`^${r}$`),o=t.match(i);if(!o)return null;let s=e.match(/:[^/]+/g)?.map(a=>a.slice(1))||[],n={};return s.forEach((a,c)=>{n[a]=o[c+1]||""}),{params:n,pathname:t,pattern:e}}import{useCallback as P}from"react";function K(){let e=R(),t=d(),r=l(),i=P((n,a)=>{let c=new URLSearchParams(e.toString());c.set(n,a);let m=c.toString(),A=`${r.pathname||"/"}${m?`?${m}`:""}`;t(A)},[e,t,r.pathname]),o=P(n=>{let a=new URLSearchParams(e.toString());a.delete(n);let c=a.toString(),u=`${r.pathname||"/"}${c?`?${c}`:""}`;t(u)},[e,t,r.pathname]),s=P(()=>{let n=r.pathname||"/";t(n)},[t,r.pathname]);return{query:e,setQuery:i,removeQuery:o,clearQueries:s}}import{useMemo as E}from"react";import{isClient as Q,FEATURE_STATUS as F}from"@donotdev/core";import{useAuthConfig as M}from"@donotdev/core";import{DEGRADED_AUTH_API as O}from"@donotdev/core";import*as U from"@donotdev/auth";var x=U?.useAuth;function L(e){return O[e]}function p(e){return x?x(e):L(e)}function j(e={}){let{auth:t,redirectTo:r,condition:i}=e;if(!Q())return{shouldRedirect:!1,redirectTo:null,isChecking:!1};let o=l(),s=M(),n=p("user"),a=p("can"),c=p("status");return E(()=>{if(c===F.INITIALIZING)return{shouldRedirect:!1,redirectTo:null,isChecking:!0};if(i){let u=i(n,c);return{shouldRedirect:u,redirectTo:u&&r||null,isChecking:!1}}if(t!==!1&&t!==void 0){if(!a)return{shouldRedirect:!1,redirectTo:null,isChecking:!1};if(!a.navigate(t)){let u=null;return typeof t=="object"&&t.required&&!n?o.search.includes("code=")||o.search.includes("state=")||o.search.includes("error=")?u=`${s.authRoute}${o.search}`:u=s.authRoute:typeof t=="object"&&t.role?u=s.roleRoute:typeof t=="object"&&t.tier?u=s.tierRoute:u=s.roleRoute,{shouldRedirect:!0,redirectTo:r||u,isChecking:!1}}}return{shouldRedirect:!1,redirectTo:null,isChecking:!1}},[t,c,n,a,i,r,o.search,s.authRoute,s.roleRoute,s.tierRoute])}export{k as useBack,l as useLocation,$ as useMatch,d as useNavigate,g as useParams,T as usePrefetch,K as useQueryParams,j as useRedirectGuard,v as useRefresh,I as useRouteParam,R as useSearchParams};
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
export { useNavigate, useBack, useRefresh, usePrefetch, } from './useNavigate.vite';
|
|
11
11
|
export { useLocation } from './useLocation.vite';
|
|
12
12
|
export { useParams } from './useParams.vite';
|
|
13
|
+
export { useRouteParam } from './useRouteParam.vite';
|
|
13
14
|
export { useSearchParams } from './useSearchParams.vite';
|
|
14
15
|
export { useMatch } from './useMatch.vite';
|
|
15
16
|
export { useQueryParams } from './useQueryParams.vite';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.vite.d.ts","sourceRoot":"","sources":["../../../src/routing/hooks/hooks.vite.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AAEH,OAAO,EACL,WAAW,EACX,OAAO,EACP,UAAU,EACV,WAAW,GACZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,YAAY,EACV,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"hooks.vite.d.ts","sourceRoot":"","sources":["../../../src/routing/hooks/hooks.vite.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AAEH,OAAO,EACL,WAAW,EACX,OAAO,EACP,UAAU,EACV,WAAW,GACZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,YAAY,EACV,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,yBAAyB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{useCallback as m}from"react";import{useNavigate as
|
|
1
|
+
"use client";import{useCallback as m}from"react";import{useNavigate as P}from"react-router-dom";import{isClient as y,useOverlayStore as S}from"@donotdev/core";function h(){let e=P(),t=S(r=>r.closeAll);return m((r,i)=>r==="back"?(t(),e(-1)):(t(),i?.replace?e(r,{replace:!0}):e(r)),[e,t])}function v(){let e=P();return m(()=>e(-1),[e])}function k(){return m(()=>{y()&&window.location.reload()},[])}function T(){return m(e=>{},[])}import{useLocation as C}from"react-router-dom";function f(){return C()}import{useParams as I}from"react-router-dom";function d(){return I()}function b(e){let r=d()[e];if(typeof r=="string")return r;if(Array.isArray(r)&&r.length>0)return r[0]}import{useSearchParams as G}from"react-router-dom";function g(){return G()[0]}import{useMatch as w}from"react-router-dom";function N(e){return w(e)}import{useCallback as R}from"react";function K(){let e=g(),t=h(),r=f(),i=R((n,u)=>{let a=new URLSearchParams(e.toString());a.set(n,u);let l=a.toString(),A=`${r.pathname||"/"}${l?`?${l}`:""}`;t(A)},[e,t,r.pathname]),c=R(n=>{let u=new URLSearchParams(e.toString());u.delete(n);let a=u.toString(),o=`${r.pathname||"/"}${a?`?${a}`:""}`;t(o)},[e,t,r.pathname]),s=R(()=>{let n=r.pathname||"/";t(n)},[t,r.pathname]);return{query:e,setQuery:i,removeQuery:c,clearQueries:s}}import{useMemo as $}from"react";import{isClient as M,FEATURE_STATUS as Q}from"@donotdev/core";import{useAuthConfig as E}from"@donotdev/core";import{DEGRADED_AUTH_API as L}from"@donotdev/core";import*as O from"@donotdev/auth";var x=O?.useAuth;function U(e){return L[e]}function p(e){return x?x(e):U(e)}function _(e={}){let{auth:t,redirectTo:r,condition:i}=e;if(!M())return{shouldRedirect:!1,redirectTo:null,isChecking:!1};let c=f(),s=E(),n=p("user"),u=p("can"),a=p("status");return $(()=>{if(a===Q.INITIALIZING)return{shouldRedirect:!1,redirectTo:null,isChecking:!0};if(i){let o=i(n,a);return{shouldRedirect:o,redirectTo:o&&r||null,isChecking:!1}}if(t!==!1&&t!==void 0){if(!u)return{shouldRedirect:!1,redirectTo:null,isChecking:!1};if(!u.navigate(t)){let o=null;return typeof t=="object"&&t.required&&!n?c.search.includes("code=")||c.search.includes("state=")||c.search.includes("error=")?o=`${s.authRoute}${c.search}`:o=s.authRoute:typeof t=="object"&&t.role?o=s.roleRoute:typeof t=="object"&&t.tier?o=s.tierRoute:o=s.roleRoute,{shouldRedirect:!0,redirectTo:r||o,isChecking:!1}}}return{shouldRedirect:!1,redirectTo:null,isChecking:!1}},[t,a,n,u,i,r,c.search,s.authRoute,s.roleRoute,s.tierRoute])}export{v as useBack,f as useLocation,N as useMatch,h as useNavigate,d as useParams,T as usePrefetch,K as useQueryParams,_ as useRedirectGuard,k as useRefresh,b as useRouteParam,g as useSearchParams};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safely extract a route parameter as a string
|
|
3
|
+
*
|
|
4
|
+
* Handles the fact that useParams can return string | string[] | undefined.
|
|
5
|
+
* For standard path parameters (not catch-all routes), this will always be a string.
|
|
6
|
+
*
|
|
7
|
+
* @param paramName - Name of the route parameter
|
|
8
|
+
* @returns The parameter value as a string, or undefined if not present
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* // Route: /product/:id
|
|
13
|
+
* const id = useRouteParam('id'); // string | undefined
|
|
14
|
+
* if (!id) return <NotFound />;
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare function useRouteParam(paramName: string): string | undefined;
|
|
18
|
+
//# sourceMappingURL=useRouteParam.next.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRouteParam.next.d.ts","sourceRoot":"","sources":["../../../src/routing/hooks/useRouteParam.next.ts"],"names":[],"mappings":"AAcA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAanE"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
// packages/ui/src/routing/hooks/useRouteParam.next.ts
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview useRouteParam hook - Next.js implementation
|
|
5
|
+
* @description Helper hook to safely extract a single route parameter as a string
|
|
6
|
+
*
|
|
7
|
+
* @version 0.0.1
|
|
8
|
+
* @since 0.0.1
|
|
9
|
+
* @author AMBROISE PARK Consulting
|
|
10
|
+
*/
|
|
11
|
+
import { useParams } from './useParams.next';
|
|
12
|
+
/**
|
|
13
|
+
* Safely extract a route parameter as a string
|
|
14
|
+
*
|
|
15
|
+
* Handles the fact that useParams can return string | string[] | undefined.
|
|
16
|
+
* For standard path parameters (not catch-all routes), this will always be a string.
|
|
17
|
+
*
|
|
18
|
+
* @param paramName - Name of the route parameter
|
|
19
|
+
* @returns The parameter value as a string, or undefined if not present
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```tsx
|
|
23
|
+
* // Route: /product/:id
|
|
24
|
+
* const id = useRouteParam('id'); // string | undefined
|
|
25
|
+
* if (!id) return <NotFound />;
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export function useRouteParam(paramName) {
|
|
29
|
+
const params = useParams();
|
|
30
|
+
const value = params[paramName];
|
|
31
|
+
if (typeof value === 'string') {
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
if (Array.isArray(value) && value.length > 0) {
|
|
35
|
+
return value[0];
|
|
36
|
+
}
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safely extract a route parameter as a string
|
|
3
|
+
*
|
|
4
|
+
* Handles the fact that useParams can return string | string[] | undefined.
|
|
5
|
+
* For standard path parameters (not catch-all routes), this will always be a string.
|
|
6
|
+
*
|
|
7
|
+
* @param paramName - Name of the route parameter
|
|
8
|
+
* @returns The parameter value as a string, or undefined if not present
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* // Route: /product/:id
|
|
13
|
+
* const id = useRouteParam('id'); // string | undefined
|
|
14
|
+
* if (!id) return <NotFound />;
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare function useRouteParam(paramName: string): string | undefined;
|
|
18
|
+
//# sourceMappingURL=useRouteParam.vite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRouteParam.vite.d.ts","sourceRoot":"","sources":["../../../src/routing/hooks/useRouteParam.vite.ts"],"names":[],"mappings":"AAcA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAanE"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
// packages/ui/src/routing/hooks/useRouteParam.vite.ts
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview useRouteParam hook - Vite/React Router implementation
|
|
5
|
+
* @description Helper hook to safely extract a single route parameter as a string
|
|
6
|
+
*
|
|
7
|
+
* @version 0.0.1
|
|
8
|
+
* @since 0.0.1
|
|
9
|
+
* @author AMBROISE PARK Consulting
|
|
10
|
+
*/
|
|
11
|
+
import { useParams } from './useParams.vite';
|
|
12
|
+
/**
|
|
13
|
+
* Safely extract a route parameter as a string
|
|
14
|
+
*
|
|
15
|
+
* Handles the fact that useParams can return string | string[] | undefined.
|
|
16
|
+
* For standard path parameters (not catch-all routes), this will always be a string.
|
|
17
|
+
*
|
|
18
|
+
* @param paramName - Name of the route parameter
|
|
19
|
+
* @returns The parameter value as a string, or undefined if not present
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```tsx
|
|
23
|
+
* // Route: /product/:id
|
|
24
|
+
* const id = useRouteParam('id'); // string | undefined
|
|
25
|
+
* if (!id) return <NotFound />;
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export function useRouteParam(paramName) {
|
|
29
|
+
const params = useParams();
|
|
30
|
+
const value = params[paramName];
|
|
31
|
+
if (typeof value === 'string') {
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
if (Array.isArray(value) && value.length > 0) {
|
|
35
|
+
return value[0];
|
|
36
|
+
}
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
package/dist/routing/index.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export { default as GoToWrapper } from './GoToWrapper';
|
|
|
15
15
|
export { default as GoToInput } from './GoToInput';
|
|
16
16
|
export * from './DnDevNavigationMenu';
|
|
17
17
|
export { default as NotFoundPage } from './404';
|
|
18
|
-
export { useNavigate, useBack, useRefresh, usePrefetch, useLocation, useParams, useSearchParams, useMatch, useQueryParams, useRedirectGuard, } from '@donotdev/ui/routing/hooks';
|
|
18
|
+
export { useNavigate, useBack, useRefresh, usePrefetch, useLocation, useParams, useRouteParam, useSearchParams, useMatch, useQueryParams, useRedirectGuard, } from '@donotdev/ui/routing/hooks';
|
|
19
19
|
export type { NavigateOptions, RedirectGuardOptions, RedirectGuardResult, } from '@donotdev/ui/routing/hooks';
|
|
20
20
|
export * from './useNavigation';
|
|
21
21
|
export * from './useGoTo';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/routing/index.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAGH,cAAc,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,QAAQ,CAAC;AACvB,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAC;AAEnD,cAAc,uBAAuB,CAAC;AACtC,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,OAAO,CAAC;AAOhD,OAAO,EACL,WAAW,EACX,OAAO,EACP,UAAU,EACV,WAAW,EACX,WAAW,EACX,SAAS,EACT,eAAe,EACf,QAAQ,EACR,cAAc,EACd,gBAAgB,GACjB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACV,eAAe,EACf,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/routing/index.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAGH,cAAc,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,QAAQ,CAAC;AACvB,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAC;AAEnD,cAAc,uBAAuB,CAAC;AACtC,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,OAAO,CAAC;AAOhD,OAAO,EACL,WAAW,EACX,OAAO,EACP,UAAU,EACV,WAAW,EACX,WAAW,EACX,SAAS,EACT,aAAa,EACb,eAAe,EACf,QAAQ,EACR,cAAc,EACd,gBAAgB,GACjB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACV,eAAe,EACf,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC"}
|
package/dist/routing/index.js
CHANGED
|
@@ -23,6 +23,6 @@ export { default as NotFoundPage } from './404';
|
|
|
23
23
|
// - hooks.vite.ts when bundled with Vite (vite-app condition)
|
|
24
24
|
// - hooks.next.ts when bundled with Next.js (default condition)
|
|
25
25
|
// NOTE: Explicit named exports required - esbuild can't re-export with 'export *' from external
|
|
26
|
-
export { useNavigate, useBack, useRefresh, usePrefetch, useLocation, useParams, useSearchParams, useMatch, useQueryParams, useRedirectGuard, } from '@donotdev/ui/routing/hooks';
|
|
26
|
+
export { useNavigate, useBack, useRefresh, usePrefetch, useLocation, useParams, useRouteParam, useSearchParams, useMatch, useQueryParams, useRedirectGuard, } from '@donotdev/ui/routing/hooks';
|
|
27
27
|
export * from './useNavigation';
|
|
28
28
|
export * from './useGoTo';
|