@donotdev/ui 0.0.14 → 0.0.16
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/dist/components/common/TechBento.d.ts.map +1 -1
- package/dist/components/common/TechBento.js +1 -1
- package/dist/components/layout/components/header/HeaderNavigation.d.ts.map +1 -1
- package/dist/components/layout/components/header/HeaderNavigation.js +2 -2
- package/dist/components/layout/components/index.d.ts +3 -0
- package/dist/components/layout/components/index.d.ts.map +1 -1
- package/dist/components/layout/components/index.js +3 -0
- package/dist/crud/components/CrudCardLink.d.ts.map +1 -1
- package/dist/crud/components/EntityCardList.d.ts +1 -1
- package/dist/crud/components/EntityCardList.d.ts.map +1 -1
- package/dist/crud/components/EntityCardList.js +24 -35
- package/dist/crud/components/EntityDisplayRenderer.d.ts +1 -1
- package/dist/crud/components/EntityDisplayRenderer.d.ts.map +1 -1
- package/dist/crud/components/EntityDisplayRenderer.js +6 -2
- package/dist/crud/components/EntityFormRenderer.d.ts +1 -1
- package/dist/crud/components/EntityFormRenderer.d.ts.map +1 -1
- package/dist/crud/components/EntityFormRenderer.js +12 -29
- package/dist/crud/components/EntityList.d.ts.map +1 -1
- package/dist/crud/components/EntityList.js +7 -43
- package/dist/crud/components/EntityRecommendations.d.ts +1 -0
- package/dist/crud/components/EntityRecommendations.d.ts.map +1 -1
- package/dist/crud/components/EntityRecommendations.js +3 -2
- package/dist/dndev.css +11581 -0
- package/dist/index.js +4 -4
- package/dist/internal/devtools/components/DesignTab.d.ts.map +1 -1
- package/dist/internal/layout/components/AutoMetaTags.d.ts.map +1 -1
- package/dist/internal/layout/components/AutoMetaTags.js +2 -9
- package/dist/internal/layout/components/FontPreloadLinks.d.ts.map +1 -1
- package/dist/internal/layout/components/FontPreloadLinks.js +1 -0
- package/dist/internal/layout/components/footer/useLegalLinks.d.ts.map +1 -1
- package/dist/internal/providers/NavigationProvider.d.ts.map +1 -1
- package/dist/internal/providers/NavigationProvider.js +3 -5
- package/dist/providers/ViteAppProviders.d.ts.map +1 -1
- package/dist/providers/ViteAppProviders.js +3 -5
- package/dist/routing/GoToInput.d.ts.map +1 -1
- package/dist/routing/GoToInput.js +6 -6
- package/dist/routing/Link.d.ts.map +1 -1
- package/dist/routing/hooks/hooks.next.js +1 -1
- package/dist/routing/hooks/hooks.vite.js +1 -1
- package/dist/routing/hooks/useNavigate.next.d.ts +1 -1
- package/dist/routing/hooks/useNavigate.next.d.ts.map +1 -1
- package/dist/routing/hooks/useNavigate.next.js +1 -7
- package/dist/routing/hooks/useNavigate.vite.d.ts +1 -1
- package/dist/routing/hooks/useNavigate.vite.d.ts.map +1 -1
- package/dist/routing/hooks/useNavigate.vite.js +1 -7
- package/dist/routing/useRouteDiscovery.d.ts +4 -15
- package/dist/routing/useRouteDiscovery.d.ts.map +1 -1
- package/dist/routing/useRouteDiscovery.js +6 -5
- package/dist/styles/index.css +96 -63
- package/dist/utils/sanitizeSvg.d.ts.map +1 -1
- package/dist/utils/useFormStoreSafe.d.ts +2 -15
- package/dist/utils/useFormStoreSafe.d.ts.map +1 -1
- package/dist/utils/useFormStoreSafe.js +3 -33
- package/dist/vite-routing/AppRoutes.d.ts.map +1 -1
- package/dist/vite-routing/AppRoutes.js +1 -1
- package/dist/vite-routing/RootLayout.d.ts.map +1 -1
- package/dist/vite-routing/RootLayout.js +10 -15
- package/package.json +10 -10
- package/dist/routing/hooks/useFormNavigationBlocker.d.ts +0 -14
- package/dist/routing/hooks/useFormNavigationBlocker.d.ts.map +0 -1
- package/dist/routing/hooks/useFormNavigationBlocker.js +0 -42
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DesignTab.d.ts","sourceRoot":"","sources":["../../../../src/internal/devtools/components/DesignTab.tsx"],"names":[],"mappings":"AA+CA,eAAO,MAAM,SAAS,+
|
|
1
|
+
{"version":3,"file":"DesignTab.d.ts","sourceRoot":"","sources":["../../../../src/internal/devtools/components/DesignTab.tsx"],"names":[],"mappings":"AA+CA,eAAO,MAAM,SAAS,+CAizBrB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AutoMetaTags.d.ts","sourceRoot":"","sources":["../../../../src/internal/layout/components/AutoMetaTags.tsx"],"names":[],"mappings":"AA0DA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAyE3C;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"AutoMetaTags.d.ts","sourceRoot":"","sources":["../../../../src/internal/layout/components/AutoMetaTags.tsx"],"names":[],"mappings":"AA0DA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAyE3C;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,YAAY,EAAE,aAyM1B,CAAC;AAEF;;;GAGG;AAEH,eAAe,YAAY,CAAC"}
|
|
@@ -130,7 +130,7 @@ export const AutoMetaTags = () => {
|
|
|
130
130
|
const metaData = useMemo(() => {
|
|
131
131
|
if (!seoConfig)
|
|
132
132
|
return null;
|
|
133
|
-
const { defaultNamespace = 'home', defaultImage
|
|
133
|
+
const { defaultNamespace = 'home', defaultImage } = seoConfig;
|
|
134
134
|
// Construct absolute URL for canonical link
|
|
135
135
|
const currentUrl = `${baseUrl}${location.pathname}`;
|
|
136
136
|
const ns = routeMeta.ns || defaultNamespace;
|
|
@@ -169,14 +169,7 @@ export const AutoMetaTags = () => {
|
|
|
169
169
|
publishDate: routeMeta.publishDate,
|
|
170
170
|
modifiedDate: routeMeta.modifiedDate,
|
|
171
171
|
};
|
|
172
|
-
}, [
|
|
173
|
-
location.pathname,
|
|
174
|
-
routeMeta,
|
|
175
|
-
siteName,
|
|
176
|
-
baseUrl,
|
|
177
|
-
seoConfig,
|
|
178
|
-
t,
|
|
179
|
-
]);
|
|
172
|
+
}, [location.pathname, routeMeta, siteName, baseUrl, seoConfig, t]);
|
|
180
173
|
// Return null if SEO is disabled — after all hooks have been called
|
|
181
174
|
if (!seoConfig || !metaData)
|
|
182
175
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FontPreloadLinks.d.ts","sourceRoot":"","sources":["../../../../src/internal/layout/components/FontPreloadLinks.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"FontPreloadLinks.d.ts","sourceRoot":"","sources":["../../../../src/internal/layout/components/FontPreloadLinks.tsx"],"names":[],"mappings":"AACA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AASvC;;;GAGG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,SAAS,CAAC,CAyB3D;AAED,eAAe,gBAAgB,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
// packages/ui/src/internal/layout/components/FontPreloadLinks.tsx
|
|
2
3
|
/**
|
|
3
4
|
* @fileoverview FontPreloadLinks - Server-only component for Next.js
|
|
4
5
|
* @description Reads public/dndev-font-preloads.json (written at build by FontPreloadWebpackPlugin) and renders preload link tags for Lighthouse-friendly LCP. Include in root layout so initial HTML contains the links.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLegalLinks.d.ts","sourceRoot":"","sources":["../../../../../src/internal/layout/components/footer/useLegalLinks.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAQD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"useLegalLinks.d.ts","sourceRoot":"","sources":["../../../../../src/internal/layout/components/footer/useLegalLinks.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAQD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GACxB,cAAc,WAAW,CAAC,QAAQ,CAAC,KAClC,eAAe,EAQjB,CAAC;AAEF,4CAA4C;AAC5C,eAAO,MAAM,aAAa,iBAZV,WAAW,CAAC,QAAQ,CAAC,KAClC,eAAe,EAWwB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NavigationProvider.d.ts","sourceRoot":"","sources":["../../../src/internal/providers/NavigationProvider.tsx"],"names":[],"mappings":"AAgCA,OAAO,EAAkB,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAIvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"NavigationProvider.d.ts","sourceRoot":"","sources":["../../../src/internal/providers/NavigationProvider.tsx"],"names":[],"mappings":"AAgCA,OAAO,EAAkB,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAIvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC;;GAEG;AACH,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAExD;;GAEG;AACH,UAAU,uBAAuB;IAC/B,6CAA6C;IAC7C,MAAM,EAAE,SAAS,CAAC;IAClB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,MAAM,EAAE,EAAE,uBAAuB,2CAkBrE"}
|
|
@@ -53,20 +53,18 @@ import { useAbortControllerStore, useOverlayStore } from '@donotdev/core';
|
|
|
53
53
|
* @author AMBROISE PARK Consulting
|
|
54
54
|
*/
|
|
55
55
|
export function NavigationProvider({ router }) {
|
|
56
|
-
const abortAll = useAbortControllerStore((state) => state.abortAll);
|
|
57
|
-
const closeAll = useOverlayStore((state) => state.closeAll);
|
|
58
56
|
useEffect(() => {
|
|
59
57
|
// Subscribe to navigation events using router.subscribe()
|
|
60
58
|
// This replaces the useLocation() + useEffect pattern from the old implementation
|
|
61
59
|
const unsubscribe = router.subscribe(() => {
|
|
62
60
|
// When navigation occurs, abort all pending requests and close overlays
|
|
63
61
|
// This prevents memory leaks and race conditions
|
|
64
|
-
abortAll();
|
|
65
|
-
closeAll();
|
|
62
|
+
useAbortControllerStore.getState().abortAll();
|
|
63
|
+
useOverlayStore.getState().closeAll();
|
|
66
64
|
});
|
|
67
65
|
// Cleanup subscription on unmount
|
|
68
66
|
return unsubscribe;
|
|
69
|
-
}, [router
|
|
67
|
+
}, [router]);
|
|
70
68
|
// RouterProvider manages its own children from the router configuration
|
|
71
69
|
// No need to render children prop (kept for backwards compatibility)
|
|
72
70
|
return _jsx(RouterProvider, { router: router });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ViteAppProviders.d.ts","sourceRoot":"","sources":["../../src/providers/ViteAppProviders.tsx"],"names":[],"mappings":"AAcA,OAAO,aAAa,CAAC;AACrB,OAAO,gBAAgB,CAAC;AACxB,OAAO,sBAAsB,CAAC;AAC9B,OAAO,gBAAgB,CAAC;AACxB,OAAO,gBAAgB,CAAC;AAGxB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AA2BxD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"ViteAppProviders.d.ts","sourceRoot":"","sources":["../../src/providers/ViteAppProviders.tsx"],"names":[],"mappings":"AAcA,OAAO,aAAa,CAAC;AACrB,OAAO,gBAAgB,CAAC;AACxB,OAAO,sBAAsB,CAAC;AAC9B,OAAO,gBAAgB,CAAC;AACxB,OAAO,gBAAgB,CAAC;AAGxB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AA2BxD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,iBAAiB,2CAmCxD"}
|
|
@@ -8,7 +8,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
8
8
|
* @since 0.0.1
|
|
9
9
|
* @author AMBROISE PARK Consulting
|
|
10
10
|
*/
|
|
11
|
-
import { lazy, Suspense } from 'react';
|
|
11
|
+
import { lazy, Suspense, useMemo } from 'react';
|
|
12
12
|
// Import virtual modules to populate globalThis._DNDEV_CONFIG_ before any components load
|
|
13
13
|
import 'virtual:env';
|
|
14
14
|
import 'virtual:themes';
|
|
@@ -76,9 +76,7 @@ export function ViteAppProviders(props) {
|
|
|
76
76
|
// Create router instance using React Router v7 data router pattern
|
|
77
77
|
// Virtual modules are loaded at module level (lines 20-26), so routes are available
|
|
78
78
|
// HomePage.tsx is automatically assigned path "/" by RouteDiscovery convention
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
layout,
|
|
82
|
-
});
|
|
79
|
+
// Memoized so the router instance is stable across re-renders (Item 86)
|
|
80
|
+
const router = useMemo(() => createAppRouter({ routeGroups, layout }), [routeGroups, layout]);
|
|
83
81
|
return (_jsxs(AppConfigProvider, { config: config, platform: "vite", children: [_jsx(SentryInitializer, {}), _jsx(ViteStoresInitializer, { customStores: customStores, children: _jsx(Suspense, { fallback: null, children: _jsxs(HelmetProvider, { children: [_jsx(FaviconHead, {}), _jsx(PerformanceHints, {}), _jsx(NavigationProvider, { router: router })] }) }) })] }));
|
|
84
82
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GoToInput.d.ts","sourceRoot":"","sources":["../../src/routing/GoToInput.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GoToInput.d.ts","sourceRoot":"","sources":["../../src/routing/GoToInput.tsx"],"names":[],"mappings":"AAgCA,QAAA,MAAM,SAAS,+CAwEd,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
|
@@ -17,12 +17,12 @@ import { useTranslation } from '@donotdev/core';
|
|
|
17
17
|
* Navigation input - typeable search that syncs with command dialog
|
|
18
18
|
*/
|
|
19
19
|
/** Detect macOS/iOS for keyboard shortcut label (defaults to ⌘K during SSR) */
|
|
20
|
-
const isMac = typeof navigator !== 'undefined' &&
|
|
20
|
+
const isMac = typeof navigator !== 'undefined' &&
|
|
21
|
+
/Mac|iPhone|iPad/.test(navigator.userAgent);
|
|
21
22
|
const GoToInput = () => {
|
|
22
23
|
const { t } = useTranslation('dndev');
|
|
23
24
|
const [value, setValue] = useState('');
|
|
24
25
|
const inputRef = useRef(null);
|
|
25
|
-
const openCommandDialog = useOverlayStore((state) => state.openCommandDialog);
|
|
26
26
|
const isCommandDialogOpen = useOverlayStore((state) => state.isCommandDialogOpen);
|
|
27
27
|
// Clear input when dialog closes
|
|
28
28
|
useEffect(() => {
|
|
@@ -31,14 +31,14 @@ const GoToInput = () => {
|
|
|
31
31
|
}
|
|
32
32
|
}, [isCommandDialogOpen]);
|
|
33
33
|
const handleFocus = useCallback(() => {
|
|
34
|
-
openCommandDialog(value);
|
|
35
|
-
}, [
|
|
34
|
+
useOverlayStore.getState().openCommandDialog(value);
|
|
35
|
+
}, [value]);
|
|
36
36
|
const handleKeyDown = useCallback((e) => {
|
|
37
37
|
if (e.key === 'Enter') {
|
|
38
38
|
e.preventDefault();
|
|
39
|
-
openCommandDialog(value);
|
|
39
|
+
useOverlayStore.getState().openCommandDialog(value);
|
|
40
40
|
}
|
|
41
|
-
}, [
|
|
41
|
+
}, [value]);
|
|
42
42
|
return (_jsxs(Stack, { direction: "row", align: "center", className: "dndev-relative dndev-w-full dndev-max-w-sm", role: "search", children: [_jsx(Search, { className: "dndev-absolute dndev-size-md", style: { insetInlineStart: '0.75rem', opacity: 0.5 }, "aria-hidden": "true" }), _jsx("input", { ref: inputRef, type: "text", value: value, onChange: (e) => setValue(e.target.value), onFocus: handleFocus, onKeyDown: handleKeyDown, placeholder: t('globalGoTo.searchPlaceholder', 'Search pages...'), className: "dndev-input dndev-w-full", style: { paddingInlineStart: '2.5rem', paddingInlineEnd: '5rem' }, "aria-label": t('globalGoTo.ariaLabel', 'Search navigation') }), _jsx("div", { className: "dndev-absolute dndev-flex dndev-items-center dndev-text-sm", style: { insetInlineEnd: '0.75rem', gap: '0.25rem', opacity: 0.5 }, "aria-hidden": "true", children: _jsx("kbd", { style: {
|
|
43
43
|
padding: '0.25rem 0.5rem',
|
|
44
44
|
fontSize: 'var(--font-size-xs)',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../../src/routing/Link.tsx"],"names":[],"mappings":"AAaA,OAAO,EACL,KAAK,SAAS,EACd,KAAK,aAAa,EAElB,KAAK,oBAAoB,EAC1B,MAAM,OAAO,CAAC;AASf;;;;;;GAMG;AACH,MAAM,WAAW,SAAU,SAAQ,oBAAoB,CAAC,iBAAiB,CAAC;IACxE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,oCAAoC;IACpC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,eAAO,MAAM,IAAI,EAAE,aAAa,CAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../../src/routing/Link.tsx"],"names":[],"mappings":"AAaA,OAAO,EACL,KAAK,SAAS,EACd,KAAK,aAAa,EAElB,KAAK,oBAAoB,EAC1B,MAAM,OAAO,CAAC;AASf;;;;;;GAMG;AACH,MAAM,WAAW,SAAU,SAAQ,oBAAoB,CAAC,iBAAiB,CAAC;IACxE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,oCAAoC;IACpC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,eAAO,MAAM,IAAI,EAAE,aAAa,CAAC,SAAS,CAuIzC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{useRouter as
|
|
1
|
+
"use client";import{useRouter as f}from"next/navigation";import{useCallback as h}from"react";import{isClient as S,useOverlayStore as y}from"@donotdev/core";function d(){let e=f(),t=y(r=>r.closeAll);return h((r,i)=>{if(r==="back")return t(),e.back();if(t(),i?.preserveScroll&&S()){let s=window.scrollY;i?.replace?e.replace(r):e.push(r),requestAnimationFrame(()=>{window.scrollTo({top:s,behavior:"auto"})});return}return i?.replace?e.replace(r):e.push(r)},[e,t])}function k(){let e=f();return h(()=>e.back(),[e])}function T(){let e=f();return h(()=>e.refresh(),[e])}function v(){let e=f();return h(t=>e.prefetch(t),[e])}import{usePathname as b,useSearchParams as N}from"next/navigation";function l(){let e=b(),t=N(),r=t.toString()?`?${t.toString()}`:"";return{pathname:e||"/",search:r,hash:"",state:null}}import{useParams as w}from"next/navigation";function g(){return w()}function C(e){let r=g()[e];if(typeof r=="string")return r;if(Array.isArray(r)&&r.length>0)return r[0]}import{useSearchParams as I}from"next/navigation";function R(){return I()}import{usePathname as G}from"next/navigation";function $(e){let t=G(),r=e.replace(/:[^/]+/g,"([^/]+)").replace(/\*/g,".*"),i=new RegExp(`^${r}$`),s=t.match(i);if(!s)return null;let o=e.match(/:[^/]+/g)?.map(a=>a.slice(1))||[],n={};return o.forEach((a,c)=>{n[a]=s[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(),x=`${r.pathname||"/"}${m?`?${m}`:""}`;t(x)},[e,t,r.pathname]),s=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]),o=P(()=>{let n=r.pathname||"/";t(n)},[t,r.pathname]);return{query:e,setQuery:i,removeQuery:s,clearQueries:o}}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*as O from"@donotdev/auth";import{DEGRADED_AUTH_API as U}from"@donotdev/core";var A=O?.useAuth;function L(e){return U[e]}function p(e){return A?A(e):L(e)}function j(e={}){let{auth:t,redirectTo:r,condition:i}=e,s=l(),o=M(),n=p("user"),a=p("can"),c=p("status");return E(()=>{if(!Q())return{shouldRedirect:!1,redirectTo:null,isChecking:!1};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?s.search.includes("code=")||s.search.includes("state=")||s.search.includes("error=")?u=`${o.authRoute}${s.search}`:u=o.authRoute:typeof t=="object"&&t.role?u=o.roleRoute:typeof t=="object"&&t.tier?u=o.tierRoute:u=o.roleRoute,{shouldRedirect:!0,redirectTo:r||u,isChecking:!1}}}return{shouldRedirect:!1,redirectTo:null,isChecking:!1}},[t,c,n,a,i,r,s.search,o.authRoute,o.roleRoute,o.tierRoute])}export{k as useBack,l as useLocation,$ as useMatch,d as useNavigate,g as useParams,v as usePrefetch,K as useQueryParams,j as useRedirectGuard,T as useRefresh,C as useRouteParam,R as useSearchParams};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{useCallback 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 L(e){return w(e)}import{useCallback as R}from"react";function N(){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*as K from"@donotdev/auth";import{DEGRADED_AUTH_API as O}from"@donotdev/core";var x=K?.useAuth;function U(e){return O[e]}function p(e){return x?x(e):U(e)}function _(e={}){let{auth:t,redirectTo:r,condition:i}=e,c=f(),s=E(),n=p("user"),u=p("can"),a=p("status");return $(()=>{if(!M())return{shouldRedirect:!1,redirectTo:null,isChecking:!1};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,L as useMatch,h as useNavigate,d as useParams,T as usePrefetch,N as useQueryParams,_ as useRedirectGuard,k as useRefresh,b as useRouteParam,g as useSearchParams};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { NavigateOptions } from './types';
|
|
2
|
-
export declare function useNavigate(): (to: string, options?: NavigateOptions) =>
|
|
2
|
+
export declare function useNavigate(): (to: string, options?: NavigateOptions) => void;
|
|
3
3
|
export declare function useBack(): () => void;
|
|
4
4
|
export declare function useRefresh(): () => void;
|
|
5
5
|
export declare function usePrefetch(): (to: string) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useNavigate.next.d.ts","sourceRoot":"","sources":["../../../src/routing/hooks/useNavigate.next.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useNavigate.next.d.ts","sourceRoot":"","sources":["../../../src/routing/hooks/useNavigate.next.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,wBAAgB,WAAW,SAKlB,MAAM,YAAY,eAAe,UA0BzC;AAED,wBAAgB,OAAO,eAGtB;AAED,wBAAgB,UAAU,eAGzB;AAED,wBAAgB,WAAW,SAED,MAAM,UAC/B"}
|
|
@@ -11,20 +11,14 @@
|
|
|
11
11
|
import { useRouter as useNextRouter } from 'next/navigation';
|
|
12
12
|
import { useCallback } from 'react';
|
|
13
13
|
import { isClient, useOverlayStore } from '@donotdev/core';
|
|
14
|
-
import { checkFormNavigationSafe } from '../../utils/useFormStoreSafe';
|
|
15
14
|
export function useNavigate() {
|
|
16
15
|
const router = useNextRouter();
|
|
17
16
|
const closeAll = useOverlayStore((state) => state.closeAll);
|
|
18
|
-
return useCallback(
|
|
17
|
+
return useCallback((to, options) => {
|
|
19
18
|
if (to === 'back') {
|
|
20
19
|
closeAll();
|
|
21
20
|
return router.back();
|
|
22
21
|
}
|
|
23
|
-
// Check FormStore for dirty forms before navigation (safe - works if CRUD not installed)
|
|
24
|
-
const shouldProceed = await checkFormNavigationSafe();
|
|
25
|
-
if (!shouldProceed) {
|
|
26
|
-
return; // Navigation blocked by user
|
|
27
|
-
}
|
|
28
22
|
closeAll();
|
|
29
23
|
if (options?.preserveScroll && isClient()) {
|
|
30
24
|
const scrollY = window.scrollY;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { NavigateOptions } from './types';
|
|
2
|
-
export declare function useNavigate(): (to: string, options?: NavigateOptions) => Promise<void>;
|
|
2
|
+
export declare function useNavigate(): (to: string, options?: NavigateOptions) => void | Promise<void>;
|
|
3
3
|
export declare function useBack(): () => void | Promise<void>;
|
|
4
4
|
export declare function useRefresh(): () => void;
|
|
5
5
|
export declare function usePrefetch(): (_to: string) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useNavigate.vite.d.ts","sourceRoot":"","sources":["../../../src/routing/hooks/useNavigate.vite.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useNavigate.vite.d.ts","sourceRoot":"","sources":["../../../src/routing/hooks/useNavigate.vite.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,wBAAgB,WAAW,SAKlB,MAAM,YAAY,eAAe,0BAazC;AAED,wBAAgB,OAAO,+BAGtB;AAED,wBAAgB,UAAU,eAIzB;AAED,wBAAgB,WAAW,UACA,MAAM,UAGhC"}
|
|
@@ -11,20 +11,14 @@
|
|
|
11
11
|
import { useCallback } from 'react';
|
|
12
12
|
import { useNavigate as useRouterNavigate } from 'react-router-dom';
|
|
13
13
|
import { isClient, useOverlayStore } from '@donotdev/core';
|
|
14
|
-
import { checkFormNavigationSafe } from '../../utils/useFormStoreSafe';
|
|
15
14
|
export function useNavigate() {
|
|
16
15
|
const navigate = useRouterNavigate();
|
|
17
16
|
const closeAll = useOverlayStore((state) => state.closeAll);
|
|
18
|
-
return useCallback(
|
|
17
|
+
return useCallback((to, options) => {
|
|
19
18
|
if (to === 'back') {
|
|
20
19
|
closeAll();
|
|
21
20
|
return navigate(-1);
|
|
22
21
|
}
|
|
23
|
-
// Check FormStore for dirty forms before navigation (safe - works if CRUD not installed)
|
|
24
|
-
const shouldProceed = await checkFormNavigationSafe();
|
|
25
|
-
if (!shouldProceed) {
|
|
26
|
-
return; // Navigation blocked by user
|
|
27
|
-
}
|
|
28
22
|
closeAll();
|
|
29
23
|
if (options?.replace)
|
|
30
24
|
return navigate(to, { replace: true });
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { NavigationRoute as CoreNavigationRoute } from '@donotdev/core';
|
|
1
2
|
import type { JSX } from 'react';
|
|
2
3
|
import type { ReactNode } from 'react';
|
|
3
4
|
/**
|
|
@@ -41,22 +42,10 @@ export interface RouteGroup {
|
|
|
41
42
|
routes: RouteInfo[];
|
|
42
43
|
}
|
|
43
44
|
/**
|
|
44
|
-
* Navigation route
|
|
45
|
-
*
|
|
46
|
-
* @version 0.0.1
|
|
47
|
-
* @since 0.0.1
|
|
48
|
-
* @author AMBROISE PARK Consulting
|
|
45
|
+
* Navigation route - re-exported from @donotdev/core (Item 90)
|
|
46
|
+
* Core's version is the single source of truth with richer fields.
|
|
49
47
|
*/
|
|
50
|
-
export
|
|
51
|
-
/** Route path */
|
|
52
|
-
path: string;
|
|
53
|
-
/** Display label */
|
|
54
|
-
label: string;
|
|
55
|
-
/** Optional icon component */
|
|
56
|
-
icon?: ReactNode;
|
|
57
|
-
/** Additional route metadata */
|
|
58
|
-
meta?: any;
|
|
59
|
-
}
|
|
48
|
+
export type NavigationRoute = CoreNavigationRoute;
|
|
60
49
|
/**
|
|
61
50
|
* Hook that provides auto-discovered routes from virtual module system
|
|
62
51
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useRouteDiscovery.d.ts","sourceRoot":"","sources":["../../src/routing/useRouteDiscovery.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useRouteDiscovery.d.ts","sourceRoot":"","sources":["../../src/routing/useRouteDiscovery.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAEV,eAAe,IAAI,mBAAmB,EACvC,MAAM,gBAAgB,CAAC;AAIxB,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKvC;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACxB,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,sEAAsE;IACtE,SAAS,EAAE,MAAM,CAAC;IAClB,8DAA8D;IAC9D,UAAU,EAAE,MAAM,CAAC;IACnB,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,gCAAgC;IAChC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,kCAAkC;IAClC,IAAI,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC;IACnB,qCAAqC;IACrC,MAAM,EAAE,SAAS,EAAE,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,mBAAmB,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,iBAAiB,IAAI,UAAU,EAAE,CA2BhD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,mBAAmB,IAAI,UAAU,EAAE,CAoBlD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,6BAA6B,IAAI,eAAe,EAAE,CAcjE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,gBAK3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,gBAAgB;;;;;;SAQ/B"}
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
25
25
|
import { useMemo } from 'react';
|
|
26
|
-
import { useNavigationStore, getRoutes, getRouteManifest,
|
|
26
|
+
import { useNavigationStore, getRoutes, getRouteManifest, } from '@donotdev/core';
|
|
27
27
|
import { useAuthSafe } from '../utils/useAuthSafe';
|
|
28
28
|
/**
|
|
29
29
|
* Hook that provides auto-discovered routes from virtual module system
|
|
@@ -108,9 +108,11 @@ export function useAccessibleRoutes() {
|
|
|
108
108
|
.map((group) => ({
|
|
109
109
|
...group,
|
|
110
110
|
routes: group.routes.filter((route) => {
|
|
111
|
-
// Use same filtering logic as AuthGuard for consistency
|
|
111
|
+
// Use same filtering logic as AuthGuard for consistency (Item 88)
|
|
112
112
|
if (route.auth === false)
|
|
113
113
|
return true;
|
|
114
|
+
if (route.auth === true)
|
|
115
|
+
return !!user;
|
|
114
116
|
if (typeof route.auth === 'object' && route.auth.required) {
|
|
115
117
|
return !!user;
|
|
116
118
|
}
|
|
@@ -149,9 +151,8 @@ export function useAccessibleRoutes() {
|
|
|
149
151
|
*/
|
|
150
152
|
export function useAccessibleNavigationRoutes() {
|
|
151
153
|
const user = useAuthSafe('user');
|
|
152
|
-
const { getFilteredRoutes } = useNavigationStore();
|
|
153
154
|
return useMemo(() => {
|
|
154
|
-
const filteredRoutes = getFilteredRoutes({
|
|
155
|
+
const filteredRoutes = useNavigationStore.getState().getFilteredRoutes({
|
|
155
156
|
authenticated: !!user,
|
|
156
157
|
role: user?.role || 'user',
|
|
157
158
|
});
|
|
@@ -161,7 +162,7 @@ export function useAccessibleNavigationRoutes() {
|
|
|
161
162
|
icon: route.icon,
|
|
162
163
|
meta: route.meta,
|
|
163
164
|
}));
|
|
164
|
-
}, [
|
|
165
|
+
}, [user]);
|
|
165
166
|
}
|
|
166
167
|
/**
|
|
167
168
|
* Hook that returns all discovered routes as a flat list
|
package/dist/styles/index.css
CHANGED
|
@@ -3418,80 +3418,120 @@ em {
|
|
|
3418
3418
|
|
|
3419
3419
|
/* packages/components/src/atomic/Combobox/Combobox.css */
|
|
3420
3420
|
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
align-items: center;
|
|
3425
|
-
width: 100%;
|
|
3426
|
-
text-align: start;
|
|
3427
|
-
}
|
|
3421
|
+
/* ──────────────────────────────────────────────────
|
|
3422
|
+
Trailing icon group — flex row inside the input area
|
|
3423
|
+
────────────────────────────────────────────────── */
|
|
3428
3424
|
|
|
3429
|
-
.dndev-combobox-
|
|
3425
|
+
.dndev-combobox-trailing {
|
|
3426
|
+
position: absolute;
|
|
3427
|
+
inset-inline-end: var(--gap-sm);
|
|
3428
|
+
top: 0;
|
|
3429
|
+
height: 100%;
|
|
3430
3430
|
display: flex;
|
|
3431
|
-
justify-content: space-between;
|
|
3432
3431
|
align-items: center;
|
|
3433
|
-
|
|
3432
|
+
gap: var(--gap-tight, 4px);
|
|
3433
|
+
z-index: 1;
|
|
3434
|
+
pointer-events: none; /* pass clicks through to input by default */
|
|
3434
3435
|
}
|
|
3435
3436
|
|
|
3436
|
-
.
|
|
3437
|
-
|
|
3438
|
-
}
|
|
3437
|
+
/* Input padding: reserve space for trailing content.
|
|
3438
|
+
--combobox-pad-end is set as an inline CSS variable on .dndev-combobox-wrapper. */
|
|
3439
3439
|
|
|
3440
|
-
.dndev-combobox-
|
|
3441
|
-
|
|
3442
|
-
align-items: center;
|
|
3443
|
-
gap: var(--gap-tight);
|
|
3444
|
-
margin-inline-start: auto;
|
|
3440
|
+
.dndev-combobox-wrapper .dndev-input {
|
|
3441
|
+
padding-inline-end: var(--combobox-pad-end);
|
|
3445
3442
|
}
|
|
3446
3443
|
|
|
3447
|
-
|
|
3444
|
+
/* Action buttons (create "+", clear "X") */
|
|
3445
|
+
|
|
3446
|
+
.dndev-combobox-action-btn {
|
|
3447
|
+
all: unset;
|
|
3448
3448
|
display: flex;
|
|
3449
3449
|
align-items: center;
|
|
3450
3450
|
justify-content: center;
|
|
3451
|
+
width: var(--icon-md);
|
|
3452
|
+
height: var(--icon-md);
|
|
3453
|
+
border-radius: var(--radius-interactive, var(--radius-sm, 4px));
|
|
3451
3454
|
cursor: pointer;
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3455
|
+
pointer-events: auto; /* re-enable clicks on buttons */
|
|
3456
|
+
color: var(--muted-foreground);
|
|
3457
|
+
opacity: var(--opacity-muted, 0.5);
|
|
3458
|
+
transition:
|
|
3459
|
+
opacity var(--dur-fast) var(--ease-in-out),
|
|
3460
|
+
background-color var(--dur-fast) var(--ease-in-out);
|
|
3457
3461
|
}
|
|
3458
3462
|
|
|
3459
|
-
.dndev-combobox-
|
|
3460
|
-
|
|
3463
|
+
.dndev-combobox-action-btn:hover {
|
|
3464
|
+
opacity: 1;
|
|
3465
|
+
background-color: var(--accent, rgba(0, 0, 0, 0.06));
|
|
3466
|
+
}
|
|
3467
|
+
|
|
3468
|
+
.dndev-combobox-action-btn:focus-visible {
|
|
3461
3469
|
opacity: 1;
|
|
3462
3470
|
outline: none;
|
|
3471
|
+
box-shadow:
|
|
3472
|
+
0 0 0 2px var(--ring),
|
|
3473
|
+
0 0 0 4px rgb(from var(--ring) r g b / 0.2);
|
|
3463
3474
|
}
|
|
3464
3475
|
|
|
3465
|
-
.dndev-combobox-
|
|
3466
|
-
|
|
3467
|
-
height: var(--icon-sm);
|
|
3476
|
+
.dndev-combobox-action-btn:active {
|
|
3477
|
+
opacity: 0.8;
|
|
3468
3478
|
}
|
|
3469
3479
|
|
|
3480
|
+
.dndev-combobox-action-btn svg {
|
|
3481
|
+
width: var(--size-icon-sm, 16px);
|
|
3482
|
+
height: var(--size-icon-sm, 16px);
|
|
3483
|
+
}
|
|
3484
|
+
|
|
3485
|
+
/* Create button accent color */
|
|
3486
|
+
|
|
3487
|
+
.dndev-combobox-action-btn--create {
|
|
3488
|
+
color: var(--primary);
|
|
3489
|
+
}
|
|
3490
|
+
|
|
3491
|
+
/* Clear button */
|
|
3492
|
+
|
|
3493
|
+
.dndev-combobox-action-btn--clear {
|
|
3494
|
+
color: var(--muted-foreground);
|
|
3495
|
+
}
|
|
3496
|
+
|
|
3497
|
+
/* Chevron indicator (non-interactive, just visual) */
|
|
3498
|
+
|
|
3470
3499
|
.dndev-combobox-chevron {
|
|
3471
3500
|
width: var(--icon-md);
|
|
3472
3501
|
height: var(--icon-md);
|
|
3502
|
+
display: flex;
|
|
3503
|
+
align-items: center;
|
|
3504
|
+
justify-content: center;
|
|
3505
|
+
color: var(--muted-foreground);
|
|
3473
3506
|
opacity: var(--opacity-muted);
|
|
3507
|
+
pointer-events: none;
|
|
3508
|
+
}
|
|
3509
|
+
|
|
3510
|
+
.dndev-combobox-chevron svg {
|
|
3511
|
+
width: var(--icon-md);
|
|
3512
|
+
height: var(--icon-md);
|
|
3474
3513
|
transition: transform var(--dur-fast) var(--ease-in-out);
|
|
3475
3514
|
}
|
|
3476
3515
|
|
|
3477
|
-
|
|
3516
|
+
.dndev-combobox-open .dndev-combobox-chevron svg {
|
|
3478
3517
|
transform: rotate(180deg);
|
|
3479
3518
|
}
|
|
3480
3519
|
|
|
3481
|
-
|
|
3520
|
+
/* Spinner replaces chevron */
|
|
3521
|
+
|
|
3522
|
+
.dndev-combobox-spinner {
|
|
3482
3523
|
display: flex;
|
|
3483
3524
|
align-items: center;
|
|
3484
|
-
|
|
3485
|
-
}
|
|
3486
|
-
|
|
3487
|
-
.dndev-combobox-loading-spinner {
|
|
3525
|
+
justify-content: center;
|
|
3488
3526
|
width: var(--icon-md);
|
|
3489
3527
|
height: var(--icon-md);
|
|
3490
|
-
|
|
3491
|
-
border: 2px solid currentColor;
|
|
3492
|
-
border-top-color: transparent;
|
|
3528
|
+
pointer-events: none;
|
|
3493
3529
|
}
|
|
3494
3530
|
|
|
3531
|
+
/* ──────────────────────────────────────────────────
|
|
3532
|
+
Dropdown content
|
|
3533
|
+
────────────────────────────────────────────────── */
|
|
3534
|
+
|
|
3495
3535
|
.dndev-combobox-content {
|
|
3496
3536
|
width: var(--radix-popover-trigger-width);
|
|
3497
3537
|
min-width: var(--radix-popover-trigger-width);
|
|
@@ -3501,15 +3541,6 @@ em {
|
|
|
3501
3541
|
padding: 0;
|
|
3502
3542
|
}
|
|
3503
3543
|
|
|
3504
|
-
.dndev-combobox-search-container {
|
|
3505
|
-
padding: var(--gap-sm);
|
|
3506
|
-
border-bottom: var(--border-width) solid var(--line-2);
|
|
3507
|
-
}
|
|
3508
|
-
|
|
3509
|
-
.dndev-combobox-search-input {
|
|
3510
|
-
width: 100%;
|
|
3511
|
-
}
|
|
3512
|
-
|
|
3513
3544
|
.dndev-combobox-option {
|
|
3514
3545
|
all: unset;
|
|
3515
3546
|
display: flex;
|
|
@@ -3580,16 +3611,6 @@ em {
|
|
|
3580
3611
|
flex-shrink: 0;
|
|
3581
3612
|
}
|
|
3582
3613
|
|
|
3583
|
-
.dndev-combobox-open .dndev-input-with-trailing-icon .dndev-input-icon svg,
|
|
3584
|
-
.dndev-combobox-open .dndev-input-with-trailing-icon .dndev-input-icon > * {
|
|
3585
|
-
transform: rotate(180deg);
|
|
3586
|
-
}
|
|
3587
|
-
|
|
3588
|
-
.dndev-input-with-trailing-icon .dndev-input-icon svg,
|
|
3589
|
-
.dndev-input-with-trailing-icon .dndev-input-icon > * {
|
|
3590
|
-
transition: transform var(--dur-fast) var(--ease-in-out);
|
|
3591
|
-
}
|
|
3592
|
-
|
|
3593
3614
|
/* packages/components/src/atomic/DualCard/DualCard.css */
|
|
3594
3615
|
|
|
3595
3616
|
.dndev-dual-card {
|
|
@@ -9485,9 +9506,15 @@ main[role='main'][data-routing-animation='none'] {
|
|
|
9485
9506
|
/* Desktop: opt-in via data-footer-mode="scroll" */
|
|
9486
9507
|
|
|
9487
9508
|
.dndev-layout[data-footer-mode='scroll'] {
|
|
9488
|
-
|
|
9509
|
+
height: auto;
|
|
9510
|
+
min-height: 100dvh;
|
|
9511
|
+
max-height: none;
|
|
9512
|
+
overflow-y: visible;
|
|
9489
9513
|
overflow-x: hidden;
|
|
9490
|
-
grid-template-rows: var(--header-height)
|
|
9514
|
+
grid-template-rows: var(--header-height) minmax(
|
|
9515
|
+
calc(100dvh - var(--header-height)),
|
|
9516
|
+
auto
|
|
9517
|
+
) auto;
|
|
9491
9518
|
}
|
|
9492
9519
|
|
|
9493
9520
|
.dndev-layout[data-footer-mode='scroll'] header[role='banner'] {
|
|
@@ -9511,6 +9538,7 @@ main[role='main'][data-routing-animation='none'] {
|
|
|
9511
9538
|
.dndev-layout[data-footer-mode='scroll'] footer[role='contentinfo'] {
|
|
9512
9539
|
grid-column: 2 / -1;
|
|
9513
9540
|
height: auto;
|
|
9541
|
+
margin-top: var(--gap-lg);
|
|
9514
9542
|
}
|
|
9515
9543
|
|
|
9516
9544
|
:is(.dndev-layout[data-footer-mode='scroll'] footer[role='contentinfo']) > * {
|
|
@@ -9522,9 +9550,15 @@ main[role='main'][data-routing-animation='none'] {
|
|
|
9522
9550
|
|
|
9523
9551
|
@media (width <=1023px) {
|
|
9524
9552
|
.dndev-layout {
|
|
9525
|
-
|
|
9553
|
+
height: auto;
|
|
9554
|
+
min-height: 100dvh;
|
|
9555
|
+
max-height: none;
|
|
9556
|
+
overflow-y: visible;
|
|
9526
9557
|
overflow-x: hidden;
|
|
9527
|
-
grid-template-rows: var(--header-height)
|
|
9558
|
+
grid-template-rows: var(--header-height) minmax(
|
|
9559
|
+
calc(100dvh - var(--header-height)),
|
|
9560
|
+
auto
|
|
9561
|
+
) auto;
|
|
9528
9562
|
}
|
|
9529
9563
|
|
|
9530
9564
|
.dndev-layout header[role='banner'] {
|
|
@@ -9540,6 +9574,7 @@ main[role='main'][data-routing-animation='none'] {
|
|
|
9540
9574
|
|
|
9541
9575
|
.dndev-layout footer[role='contentinfo'] {
|
|
9542
9576
|
height: auto;
|
|
9577
|
+
margin-top: var(--gap-lg);
|
|
9543
9578
|
}
|
|
9544
9579
|
|
|
9545
9580
|
:is(.dndev-layout footer[role='contentinfo']) > * {
|
|
@@ -9587,7 +9622,6 @@ header[role='banner'] {
|
|
|
9587
9622
|
padding-inline-start: var(--content-padding);
|
|
9588
9623
|
padding-inline-end: var(--content-padding);
|
|
9589
9624
|
|
|
9590
|
-
/* Theme-aware styling - 100% controlled by theme system */
|
|
9591
9625
|
background: var(--background);
|
|
9592
9626
|
border-bottom: var(--border-hairline) solid var(--border);
|
|
9593
9627
|
|
|
@@ -9936,7 +9970,6 @@ footer[role='contentinfo'] {
|
|
|
9936
9970
|
min-height: var(--footer-height);
|
|
9937
9971
|
z-index: var(--z-footer);
|
|
9938
9972
|
|
|
9939
|
-
/* Theme-aware styling - 100% controlled by theme system */
|
|
9940
9973
|
background: var(--background);
|
|
9941
9974
|
border-top: var(--border-hairline) solid var(--border);
|
|
9942
9975
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanitizeSvg.d.ts","sourceRoot":"","sources":["../../src/utils/sanitizeSvg.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sanitizeSvg.d.ts","sourceRoot":"","sources":["../../src/utils/sanitizeSvg.ts"],"names":[],"mappings":"AAiCA;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAO/C"}
|