@donotdev/ui 0.0.13 → 0.0.14

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.
Files changed (147) hide show
  1. package/dist/components/auth/AuthMenu.d.ts.map +1 -1
  2. package/dist/components/auth/AuthMenu.js +19 -20
  3. package/dist/components/common/FeatureCard.d.ts +3 -1
  4. package/dist/components/common/FeatureCard.d.ts.map +1 -1
  5. package/dist/components/common/FeatureCard.js +2 -2
  6. package/dist/components/common/ProgressBar.js +2 -2
  7. package/dist/components/common/TechBento.d.ts +14 -2
  8. package/dist/components/common/TechBento.d.ts.map +1 -1
  9. package/dist/components/common/TechBento.js +8 -9
  10. package/dist/components/cookie-consent/CookieConsent.d.ts.map +1 -1
  11. package/dist/components/cookie-consent/CookieConsent.js +3 -4
  12. package/dist/components/layout/components/DropdownNavigation.d.ts.map +1 -1
  13. package/dist/components/layout/components/DropdownNavigation.js +3 -12
  14. package/dist/components/layout/components/FloatingLanguageSwitcher.js +1 -1
  15. package/dist/components/layout/components/Notifications.d.ts +1 -3
  16. package/dist/components/layout/components/Notifications.d.ts.map +1 -1
  17. package/dist/components/layout/components/Notifications.js +4 -2
  18. package/dist/components/layout/components/header/AppBranding.d.ts.map +1 -1
  19. package/dist/components/layout/components/header/AppBranding.js +2 -1
  20. package/dist/components/layout/components/header/AppIcon.d.ts.map +1 -1
  21. package/dist/components/layout/components/header/AppIcon.js +5 -2
  22. package/dist/components/layout/components/header/CacheSettings.d.ts.map +1 -1
  23. package/dist/components/layout/components/header/CacheSettings.js +3 -1
  24. package/dist/components/layout/components/header/HeaderNavigation.d.ts +6 -0
  25. package/dist/components/layout/components/header/HeaderNavigation.d.ts.map +1 -1
  26. package/dist/components/layout/components/header/HeaderNavigation.js +12 -2
  27. package/dist/components/license/LicenseWatermark.d.ts.map +1 -1
  28. package/dist/components/license/LicenseWatermark.js +3 -1
  29. package/dist/crud/components/CrudCardLink.d.ts +17 -0
  30. package/dist/crud/components/CrudCardLink.d.ts.map +1 -0
  31. package/dist/crud/components/CrudCardLink.js +17 -0
  32. package/dist/crud/components/EntityCardList.d.ts.map +1 -1
  33. package/dist/crud/components/EntityCardList.js +24 -79
  34. package/dist/crud/components/EntityDisplayRenderer.d.ts +1 -1
  35. package/dist/crud/components/EntityDisplayRenderer.d.ts.map +1 -1
  36. package/dist/crud/components/EntityDisplayRenderer.js +6 -2
  37. package/dist/crud/components/EntityFormRenderer.d.ts +1 -1
  38. package/dist/crud/components/EntityFormRenderer.d.ts.map +1 -1
  39. package/dist/crud/components/EntityFormRenderer.js +29 -18
  40. package/dist/crud/components/EntityList.d.ts +1 -1
  41. package/dist/crud/components/EntityList.d.ts.map +1 -1
  42. package/dist/crud/components/EntityList.js +1 -1
  43. package/dist/crud/components/EntityRecommendations.d.ts +28 -0
  44. package/dist/crud/components/EntityRecommendations.d.ts.map +1 -0
  45. package/dist/crud/components/EntityRecommendations.js +31 -0
  46. package/dist/crud/components/index.d.ts +2 -1
  47. package/dist/crud/components/index.d.ts.map +1 -1
  48. package/dist/crud/components/index.js +1 -0
  49. package/dist/index.js +4 -4
  50. package/dist/internal/common/RouteErrorFallback.d.ts.map +1 -1
  51. package/dist/internal/devtools/components/AuthDebugButton.js +1 -1
  52. package/dist/internal/devtools/components/DesignTab.d.ts.map +1 -1
  53. package/dist/internal/devtools/components/DesignTab.js +3 -2
  54. package/dist/internal/devtools/components/LayoutReset.d.ts.map +1 -1
  55. package/dist/internal/devtools/components/LayoutReset.js +2 -0
  56. package/dist/internal/devtools/components/StoresTab.d.ts.map +1 -1
  57. package/dist/internal/devtools/components/StoresTab.js +3 -0
  58. package/dist/internal/devtools/utils/envVarDiscovery.d.ts +1 -0
  59. package/dist/internal/devtools/utils/envVarDiscovery.d.ts.map +1 -1
  60. package/dist/internal/devtools/utils/envVarDiscovery.js +5 -0
  61. package/dist/internal/devtools/utils/virtualModuleInspector.d.ts.map +1 -1
  62. package/dist/internal/devtools/utils/virtualModuleInspector.js +27 -21
  63. package/dist/internal/initializers/BaseStoresInitializer.d.ts.map +1 -1
  64. package/dist/internal/initializers/BaseStoresInitializer.js +30 -6
  65. package/dist/internal/layout/components/AutoMetaTags.d.ts.map +1 -1
  66. package/dist/internal/layout/components/AutoMetaTags.js +10 -8
  67. package/dist/internal/layout/components/FontPreloadLinks.d.ts +16 -0
  68. package/dist/internal/layout/components/FontPreloadLinks.d.ts.map +1 -0
  69. package/dist/internal/layout/components/FontPreloadLinks.js +32 -0
  70. package/dist/internal/layout/components/PerformanceHints.d.ts +7 -12
  71. package/dist/internal/layout/components/PerformanceHints.d.ts.map +1 -1
  72. package/dist/internal/layout/components/PerformanceHints.js +8 -12
  73. package/dist/internal/layout/components/footer/useLegalLinks.d.ts +6 -5
  74. package/dist/internal/layout/components/footer/useLegalLinks.d.ts.map +1 -1
  75. package/dist/internal/layout/components/footer/useLegalLinks.js +6 -2
  76. package/dist/internal/layout/zones/DnDevFooter.d.ts +6 -0
  77. package/dist/internal/layout/zones/DnDevFooter.d.ts.map +1 -1
  78. package/dist/internal/layout/zones/DnDevFooter.js +10 -4
  79. package/dist/internal/layout/zones/DnDevHeader.d.ts +7 -0
  80. package/dist/internal/layout/zones/DnDevHeader.d.ts.map +1 -1
  81. package/dist/internal/layout/zones/DnDevHeader.js +7 -0
  82. package/dist/internal/layout/zones/DnDevMergedBar.d.ts +7 -0
  83. package/dist/internal/layout/zones/DnDevMergedBar.d.ts.map +1 -1
  84. package/dist/internal/layout/zones/DnDevMergedBar.js +9 -0
  85. package/dist/internal/layout/zones/DnDevSidebar.d.ts +4 -0
  86. package/dist/internal/layout/zones/DnDevSidebar.d.ts.map +1 -1
  87. package/dist/internal/layout/zones/DnDevSidebar.js +13 -1
  88. package/dist/next.d.ts +1 -0
  89. package/dist/next.d.ts.map +1 -1
  90. package/dist/next.js +1 -0
  91. package/dist/routing/AuthGuard.d.ts +1 -1
  92. package/dist/routing/AuthGuard.d.ts.map +1 -1
  93. package/dist/routing/AuthGuard.js +3 -1
  94. package/dist/routing/GoTo.d.ts.map +1 -1
  95. package/dist/routing/GoTo.js +3 -1
  96. package/dist/routing/GoToDialog.d.ts.map +1 -1
  97. package/dist/routing/GoToDialog.js +2 -7
  98. package/dist/routing/GoToInput.d.ts +0 -3
  99. package/dist/routing/GoToInput.d.ts.map +1 -1
  100. package/dist/routing/GoToInput.js +4 -2
  101. package/dist/routing/Link.js +1 -1
  102. package/dist/routing/NavigationItem.d.ts +29 -7
  103. package/dist/routing/NavigationItem.d.ts.map +1 -1
  104. package/dist/routing/NavigationItem.js +22 -6
  105. package/dist/routing/hooks/hooks.next.js +1 -1
  106. package/dist/routing/hooks/hooks.vite.js +1 -1
  107. package/dist/routing/hooks/useRedirectGuard.next.d.ts.map +1 -1
  108. package/dist/routing/hooks/useRedirectGuard.next.js +9 -8
  109. package/dist/routing/hooks/useRedirectGuard.vite.d.ts.map +1 -1
  110. package/dist/routing/hooks/useRedirectGuard.vite.js +9 -8
  111. package/dist/routing/hooks/useSearchParams.next.d.ts +18 -1
  112. package/dist/routing/hooks/useSearchParams.next.d.ts.map +1 -1
  113. package/dist/routing/hooks/useSearchParams.next.js +16 -0
  114. package/dist/routing/hooks/useSearchParams.vite.d.ts +16 -0
  115. package/dist/routing/hooks/useSearchParams.vite.d.ts.map +1 -1
  116. package/dist/routing/hooks/useSearchParams.vite.js +17 -1
  117. package/dist/routing/index.d.ts.map +1 -1
  118. package/dist/routing/index.js +2 -0
  119. package/dist/routing/useNavigation.d.ts +30 -0
  120. package/dist/routing/useNavigation.d.ts.map +1 -1
  121. package/dist/routing/useNavigation.js +40 -3
  122. package/dist/routing/useRouteDiscovery.d.ts +2 -2
  123. package/dist/routing/useRouteDiscovery.d.ts.map +1 -1
  124. package/dist/routing/useRouteDiscovery.js +10 -4
  125. package/dist/styles/index.css +268 -82
  126. package/dist/utils/index.d.ts +1 -0
  127. package/dist/utils/index.d.ts.map +1 -1
  128. package/dist/utils/index.js +1 -0
  129. package/dist/utils/sanitizeSvg.d.ts +13 -0
  130. package/dist/utils/sanitizeSvg.d.ts.map +1 -0
  131. package/dist/utils/sanitizeSvg.js +47 -0
  132. package/dist/utils/useBillingVisibility.d.ts.map +1 -1
  133. package/dist/utils/useBillingVisibility.js +0 -7
  134. package/dist/utils/useCrudSafe.d.ts +0 -2
  135. package/dist/utils/useCrudSafe.d.ts.map +1 -1
  136. package/dist/utils/useFormStoreSafe.d.ts +3 -1
  137. package/dist/utils/useFormStoreSafe.d.ts.map +1 -1
  138. package/dist/utils/useFormStoreSafe.js +4 -5
  139. package/dist/vite-routing/AppRoutes.d.ts +19 -8
  140. package/dist/vite-routing/AppRoutes.d.ts.map +1 -1
  141. package/dist/vite-routing/AppRoutes.js +0 -3
  142. package/package.json +15 -11
  143. package/assets/fonts/fonts.css +0 -206
  144. package/dist/dndev.css +0 -10733
  145. package/dist/routing/Navigate.d.ts +0 -10
  146. package/dist/routing/Navigate.d.ts.map +0 -1
  147. package/dist/routing/Navigate.js +0 -10
@@ -1 +1 @@
1
- {"version":3,"file":"AuthMenu.d.ts","sourceRoot":"","sources":["../../../src/components/auth/AuthMenu.tsx"],"names":[],"mappings":"AA4EA,OAAO,KAAkC,MAAM,OAAO,CAAC;AAEvD,OAAO,EAML,OAAO,EACR,MAAM,sBAAsB,CAAC;AAc9B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAqE3C;;;;;;;;;GASG;AACH,MAAM,WAAW,kBAAkB;IACjC,sBAAsB;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtD,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,mBAAmB;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,qFAAqF;IACrF,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,OAAO,OAAO,CAAC,CAAC;IAEjD,sBAAsB;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;;OAIG;IACH,WAAW,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAEnC,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB;AAsBD,eAAO,MAAM,QAAQ,GAAI,iFAOtB,aAAa,mDA0Of,CAAC;AAEF,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"AuthMenu.d.ts","sourceRoot":"","sources":["../../../src/components/auth/AuthMenu.tsx"],"names":[],"mappings":"AA4EA,OAAO,KAAkC,MAAM,OAAO,CAAC;AAEvD,OAAO,EAML,OAAO,EACR,MAAM,sBAAsB,CAAC;AAc9B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AA8D3C;;;;;;;;;GASG;AACH,MAAM,WAAW,kBAAkB;IACjC,sBAAsB;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtD,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,mBAAmB;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,qFAAqF;IACrF,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,OAAO,OAAO,CAAC,CAAC;IAEjD,sBAAsB;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;;OAIG;IACH,WAAW,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAEnC,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB;AAsBD,eAAO,MAAM,QAAQ,GAAI,iFAOtB,aAAa,mDA0Of,CAAC;AAEF,eAAe,QAAQ,CAAC"}
@@ -102,18 +102,10 @@ const ConfirmDeleteDialog = lazy(async () => {
102
102
  }
103
103
  });
104
104
  // Graceful degradation for useDeleteAccount hook
105
- let realUseDeleteAccount = null;
106
- // Preload useDeleteAccount (non-blocking)
107
- if (isClient()) {
108
- import('@donotdev/auth')
109
- .then((module) => {
110
- realUseDeleteAccount = module.useDeleteAccount;
111
- })
112
- .catch(() => { });
113
- }
114
- // Fallback hook that matches useDeleteAccount's hook structure
115
- function useDeleteAccountFallback() {
116
- // Always call useState to maintain hook order (matches real hook structure)
105
+ // Resolved at module level (not render level) to avoid Rules of Hooks violation.
106
+ // Once set, useDeleteAccount never changes identity during the app lifecycle.
107
+ let useDeleteAccount = () => {
108
+ // Fallback: always call useState to maintain stable hook order
117
109
  const [showConfirmDialog] = React.useState(false);
118
110
  const [showPasswordDialog] = React.useState(false);
119
111
  const [isDeleting] = React.useState(false);
@@ -127,13 +119,20 @@ function useDeleteAccountFallback() {
127
119
  confirmDelete: async () => { },
128
120
  cancel: () => { },
129
121
  };
130
- }
131
- // Hook wrapper that uses real hook if available, otherwise fallback
132
- function useDeleteAccountHook() {
133
- if (realUseDeleteAccount) {
134
- return realUseDeleteAccount();
135
- }
136
- return useDeleteAccountFallback();
122
+ };
123
+ // Preload useDeleteAccount (non-blocking)
124
+ // The hook reference is swapped before the first render in practice,
125
+ // but if the import resolves after first render, the fallback remains
126
+ // stable for that session to avoid hook order changes mid-lifecycle.
127
+ if (isClient()) {
128
+ import('@donotdev/auth')
129
+ .then((module) => {
130
+ useDeleteAccount = module.useDeleteAccount;
131
+ })
132
+ .catch((e) => {
133
+ if (process.env.NODE_ENV === 'development')
134
+ console.warn('Failed to load @donotdev/auth:', e);
135
+ });
137
136
  }
138
137
  /**
139
138
  * Resolves Lucide icon component from string name or component reference
@@ -167,7 +166,7 @@ export const AuthMenu = ({ loginPath, display = DISPLAY.AUTO, 'no-tooltip': noTo
167
166
  const profilePath = authConfig.profilePath;
168
167
  const configMenuItems = authConfig.authMenuItems || [];
169
168
  // Account deletion flow - managed by useDeleteAccount hook
170
- const deletion = useDeleteAccountHook();
169
+ const deletion = useDeleteAccount();
171
170
  /**
172
171
  * Get user display name with fallbacks
173
172
  */
@@ -13,6 +13,8 @@ export interface FeatureCardProps extends Omit<CardProps, 'content' | 'href' | '
13
13
  content?: CardContent;
14
14
  /** Route path - enables routing via Link */
15
15
  href?: string;
16
+ /** When true, apply clickable styling (cursor, hover) even without href/onClick. Use when card is a dialog trigger. */
17
+ clickable?: boolean;
16
18
  }
17
19
  /**
18
20
  * FeatureCard - Card wrapper with content array and routing
@@ -21,6 +23,6 @@ export interface FeatureCardProps extends Omit<CardProps, 'content' | 'href' | '
21
23
  * Uses Card component internally.
22
24
  * Routing via Link when href provided.
23
25
  */
24
- declare const FeatureCard: ({ icon, title, subtitle, content, href, variant, elevated, onClick, className, footer, style, ...cardProps }: FeatureCardProps) => import("react/jsx-runtime").JSX.Element;
26
+ declare const FeatureCard: ({ icon, title, subtitle, content, href, variant, elevated, onClick, className, footer, style, clickable, ...cardProps }: FeatureCardProps) => import("react/jsx-runtime").JSX.Element;
25
27
  export default FeatureCard;
26
28
  //# sourceMappingURL=FeatureCard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FeatureCard.d.ts","sourceRoot":"","sources":["../../../src/components/common/FeatureCard.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAIhF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,MAAM,kBAAkB,GAAG,WAAW,CAAC;AAE7C,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAC5C,SAAS,EACT,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,UAAU,CACvD;IACC,kDAAkD;IAClD,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,qDAAqD;IACrD,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B;;;OAGG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,4CAA4C;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;GAMG;AACH,QAAA,MAAM,WAAW,GAAI,8GAalB,gBAAgB,4CAmIlB,CAAC;AAEF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"FeatureCard.d.ts","sourceRoot":"","sources":["../../../src/components/common/FeatureCard.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAIhF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,MAAM,kBAAkB,GAAG,WAAW,CAAC;AAE7C,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAC5C,SAAS,EACT,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,UAAU,CACvD;IACC,kDAAkD;IAClD,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,qDAAqD;IACrD,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B;;;OAGG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,4CAA4C;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uHAAuH;IACvH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;GAMG;AACH,QAAA,MAAM,WAAW,GAAI,yHAclB,gBAAgB,4CA8HlB,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -21,7 +21,7 @@ import { Link } from '../../routing';
21
21
  * Uses Card component internally.
22
22
  * Routing via Link when href provided.
23
23
  */
24
- const FeatureCard = ({ icon, title, subtitle, content, href, variant, elevated, onClick, className, footer, style, ...cardProps }) => {
24
+ const FeatureCard = ({ icon, title, subtitle, content, href, variant, elevated, onClick, className, footer, style, clickable, ...cardProps }) => {
25
25
  const contentNode = renderCardContent(content);
26
26
  // Fixed height constants for consistent text sizing (2 rows each)
27
27
  const titleRowHeight = `calc(var(--font-size-lg) * var(--line-height) * 2 + var(--gap-md))`;
@@ -57,7 +57,7 @@ const FeatureCard = ({ icon, title, subtitle, content, href, variant, elevated,
57
57
  };
58
58
  // Build title with icon if provided
59
59
  const titleContent = icon ? (_jsxs(Stack, { direction: "row", align: "center", style: { width: '100%' }, children: [_jsx(IconBox, { icon: icon }), _jsx(Text, { as: "div", level: "h3", style: titleStyle, children: title })] })) : (_jsx(Text, { as: "div", level: "h3", style: titleStyle, children: title }));
60
- const card = (_jsx(Card, { variant: variant, elevated: elevated, onClick: onClick, className: className, "data-clickable": href || onClick ? 'true' : undefined, style: {
60
+ const card = (_jsx(Card, { variant: variant, elevated: elevated, onClick: onClick, className: className, "data-clickable": href || onClick || clickable ? 'true' : undefined, style: {
61
61
  paddingInlineStart: 'var(--gap-md)',
62
62
  paddingInlineEnd: 'var(--gap-md)',
63
63
  gap: 'var(--gap-md)',
@@ -67,8 +67,8 @@ const ProgressBar = ({ isActive = false, progress: controlledProgress, useFakePr
67
67
  }
68
68
  return (_jsx("div", { className: cn(className), style: {
69
69
  position: 'fixed',
70
- left: 0,
71
- right: 0,
70
+ insetInlineStart: 0,
71
+ insetInlineEnd: 0,
72
72
  zIndex: 9999,
73
73
  height: '4px',
74
74
  backgroundColor: 'transparent',
@@ -1,4 +1,4 @@
1
- import type { BentoColumns, BentoGap, CardVariant, ResponsiveCols } from '@donotdev/components';
1
+ import type { BentoColumns, BentoGap, CardVariant, ResponsiveCols, Tone } from '@donotdev/components';
2
2
  import { type TechKey } from '../../data/techLogos';
3
3
  export type TechBentoProps = {
4
4
  title?: string;
@@ -22,8 +22,20 @@ export type TechBentoProps = {
22
22
  columns?: BentoColumns;
23
23
  gap?: BentoGap;
24
24
  separator?: boolean;
25
+ /** Tone system for background colors (matches Section/CallToAction) */
26
+ tone?: Tone;
27
+ /** Content alignment @default 'center' */
28
+ align?: 'start' | 'center' | 'end';
29
+ /** Whether the section is collapsible */
30
+ collapsible?: boolean;
31
+ /** Controlled open state (when collapsible) */
32
+ open?: boolean;
33
+ /** Callback when open state changes (when collapsible) */
34
+ onOpenChange?: (open: boolean) => void;
35
+ /** Default open state (uncontrolled, when collapsible) */
36
+ defaultOpen?: boolean;
25
37
  className?: string;
26
38
  };
27
- export declare function TechBento({ title, techs, cols, columns, gap, separator, className, }: TechBentoProps): import("react/jsx-runtime").JSX.Element;
39
+ export declare function TechBento({ title, techs, cols, columns, gap, separator, tone, align, collapsible, open, onOpenChange, defaultOpen, className, }: TechBentoProps): import("react/jsx-runtime").JSX.Element;
28
40
  export default TechBento;
29
41
  //# sourceMappingURL=TechBento.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TechBento.d.ts","sourceRoot":"","sources":["../../../src/components/common/TechBento.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,cAAc,EACf,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAa,KAAK,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAI/D,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,CAAC;QACX,IAAI,EAAE,OAAO,CAAC;QACd,IAAI,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;QAC3C,OAAO,CAAC,EAAE,WAAW,CAAC;KACvB,CAAC,CAAC;IACH;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,cAAc,CAAC;IAC/B;;OAEG;IACH,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAwCF,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,KAAK,EACL,IAAQ,EACR,OAAO,EACP,GAAc,EACd,SAAiB,EACjB,SAAS,GACV,EAAE,cAAc,2CAsDhB;AAED,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"TechBento.d.ts","sourceRoot":"","sources":["../../../src/components/common/TechBento.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,cAAc,EACd,IAAI,EACL,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAa,KAAK,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAK/D,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,CAAC;QACX,IAAI,EAAE,OAAO,CAAC;QACd,IAAI,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;QAC3C,OAAO,CAAC,EAAE,WAAW,CAAC;KACvB,CAAC,CAAC;IACH;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,cAAc,CAAC;IAC/B;;OAEG;IACH,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,uEAAuE;IACvE,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,0CAA0C;IAC1C,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IACnC,yCAAyC;IACzC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,+CAA+C;IAC/C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,0DAA0D;IAC1D,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,0DAA0D;IAC1D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAwCF,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,KAAK,EACL,IAAQ,EACR,OAAO,EACP,GAAc,EACd,SAAiB,EACjB,IAAiB,EACjB,KAAK,EACL,WAAW,EACX,IAAI,EACJ,YAAY,EACZ,WAAW,EACX,SAAS,GACV,EAAE,cAAc,2CA4DhB;AAED,eAAe,SAAS,CAAC"}
@@ -1,18 +1,19 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  // packages/ui/src/components/common/TechBento.tsx
3
3
  import { useState } from 'react';
4
- import { Bento, Card, Section, Stack, Text, cn } from '@donotdev/components';
4
+ import { Bento, Card, Section, Stack, Text, TONE, cn } from '@donotdev/components';
5
5
  import { techLogos } from '../../data/techLogos';
6
+ import { sanitizeSvg } from '../../utils/sanitizeSvg';
6
7
  function TechCard({ techKey, variant, }) {
7
8
  const logo = techLogos[techKey];
8
9
  const [isHovered, setIsHovered] = useState(false);
9
10
  if (!logo)
10
11
  return null;
11
- const svgContent = logo.svg.replace('data:image/svg+xml,', '');
12
- const decodedSvg = decodeURIComponent(svgContent);
12
+ const rawSvg = decodeURIComponent(logo.svg.replace('data:image/svg+xml,', ''));
13
+ const decodedSvg = sanitizeSvg(rawSvg);
13
14
  return (_jsx(Card, { variant: variant, className: "dndev-tech-card", style: { '--tech-color': logo.color }, "data-hover": isHovered, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), children: _jsxs(Stack, { direction: "column", align: "center", gap: "tight", children: [_jsx("div", { className: "dndev-tech-card-logo", "data-tech": techKey, dangerouslySetInnerHTML: { __html: decodedSvg } }), _jsx(Text, { as: "span", level: "small", children: logo.name })] }) }));
14
15
  }
15
- export function TechBento({ title, techs, cols = 3, columns, gap = 'medium', separator = false, className, }) {
16
+ export function TechBento({ title, techs, cols = 3, columns, gap = 'medium', separator = false, tone = TONE.GHOST, align, collapsible, open, onOpenChange, defaultOpen, className, }) {
16
17
  // Convert Grid's cols format to Bento's columns format
17
18
  // Grid: [mobile, tablet, laptop, desktop]
18
19
  // Bento: { mobile, tablet, desktop, wide }
@@ -47,10 +48,8 @@ export function TechBento({ title, techs, cols = 3, columns, gap = 'medium', sep
47
48
  content: _jsx(TechCard, { techKey: tech.name, variant: tech.variant }),
48
49
  span: getSpan(tech.size),
49
50
  }));
50
- const bento = (_jsx(Bento, { items: items, columns: bentoColumns, gap: gap, className: className, ariaLabel: "Technology stack" }));
51
- if (title) {
52
- return (_jsx(Section, { title: title, separator: separator, className: "dndev-tech-bento", children: _jsx("div", { className: "dndev-tech-bento-grid", children: bento }) }));
53
- }
54
- return _jsx("div", { className: cn('dndev-tech-bento', className), children: bento });
51
+ const bento = (_jsx(Bento, { items: items, columns: bentoColumns, gap: gap, ariaLabel: "Technology stack" }));
52
+ // Always use Section - TechBento is a Section with a Bento grid
53
+ return (_jsx(Section, { title: title, separator: separator, tone: tone, align: align, collapsible: collapsible, open: open, onOpenChange: onOpenChange, defaultOpen: defaultOpen, className: cn('dndev-tech-bento', className), children: _jsx("div", { className: "dndev-tech-bento-grid", children: bento }) }));
55
54
  }
56
55
  export default TechBento;
@@ -1 +1 @@
1
- {"version":3,"file":"CookieConsent.d.ts","sourceRoot":"","sources":["../../../src/components/cookie-consent/CookieConsent.tsx"],"names":[],"mappings":"AA6BA,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;IAC5B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,iBAAS,aAAa,CAAC,EACrB,QAAmB,EACnB,YAAmB,EACnB,YAA8C,EAC9C,SAAc,GACf,EAAE,kBAAkB,kDAuUpB;AAED,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"CookieConsent.d.ts","sourceRoot":"","sources":["../../../src/components/cookie-consent/CookieConsent.tsx"],"names":[],"mappings":"AA6BA,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC;IAC5B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,iBAAS,aAAa,CAAC,EACrB,QAAmB,EACnB,YAAmB,EACnB,YAA8C,EAC9C,SAAc,GACf,EAAE,kBAAkB,kDAqUpB;AAED,eAAe,aAAa,CAAC"}
@@ -14,7 +14,6 @@ function CookieConsent({ position = 'bottom', showBranding = true, brandingText
14
14
  const declineAll = useConsent('declineAll');
15
15
  const updateCategory = useConsent('updateCategory');
16
16
  const storeShowBanner = useConsent('showBanner');
17
- const hideBanner = useConsent('showCookieBanner');
18
17
  const { t } = useTranslation('cookies');
19
18
  const [showPreferences, setShowPreferences] = useState(false);
20
19
  const [showBanner, setShowBanner] = useState(!hasConsented || storeShowBanner);
@@ -161,10 +160,10 @@ function CookieConsent({ position = 'bottom', showBranding = true, brandingText
161
160
  const bannerFooter = showPreferences ? (_jsxs(Stack, { direction: "row", gap: "tight", style: { width: '100%' }, children: [_jsx(Button, { onClick: handleSave, variant: BUTTON_VARIANT.DEFAULT, style: { flex: 1 }, children: t('savePreferences', 'Save Preferences') }), _jsx(Button, { onClick: () => setShowPreferences(false), variant: BUTTON_VARIANT.OUTLINE, style: { flex: 1 }, children: t('form.cancel', 'Cancel') })] })) : (_jsxs(Stack, { direction: "row", gap: "tight", style: { width: '100%' }, children: [_jsx(Button, { onClick: handleAcceptAll, variant: BUTTON_VARIANT.DEFAULT, style: { flex: 1 }, children: t('acceptAll') }), hasOptionalCategories && (_jsx(Button, { onClick: handleDeclineAll, variant: BUTTON_VARIANT.OUTLINE, style: { flex: 1 }, children: t('declineOptional') }))] }));
162
161
  return (_jsxs(_Fragment, { children: [showBanner && (_jsx(Card, { ref: bannerRef, className: cn('dndev-fixed dndev-z-modal', className), icon: Cookie, title: t('cookiePreferences'), content: bannerContent, footer: bannerFooter, style: {
163
162
  [position === 'top' ? 'top' : 'bottom']: 'var(--gap-md)',
164
- left: 'var(--gap-md)',
165
- right: 'var(--gap-md)',
163
+ insetInlineStart: 'var(--gap-md)',
164
+ insetInlineEnd: 'var(--gap-md)',
166
165
  maxWidth: '100%',
167
166
  width: 'calc(100% - var(--gap-md) * 2)',
168
- } })), !showBanner && !hasConsented && (_jsx(Button, { onClick: () => setShowBanner(true), className: "dndev-fixed dndev-z-toast", style: { bottom: 'var(--gap-md)', left: 'var(--gap-md)' }, icon: Cookie, title: t('cookiePreferences') }))] }));
167
+ } })), !showBanner && !hasConsented && (_jsx(Button, { onClick: () => setShowBanner(true), className: "dndev-fixed dndev-z-toast", style: { bottom: 'var(--gap-md)', insetInlineStart: 'var(--gap-md)' }, icon: Cookie, title: t('cookiePreferences') }))] }));
169
168
  }
170
169
  export default CookieConsent;
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownNavigation.d.ts","sourceRoot":"","sources":["../../../../src/components/layout/components/DropdownNavigation.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAKtD,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,kBAAkB,EAAE,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;GAaG;AACH,QAAA,MAAM,kBAAkB,EAAE,aAAa,CAAC,uBAAuB,CAyF9D,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"DropdownNavigation.d.ts","sourceRoot":"","sources":["../../../../src/components/layout/components/DropdownNavigation.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAKtD,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,kBAAkB,EAAE,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;GAaG;AACH,QAAA,MAAM,kBAAkB,EAAE,aAAa,CAAC,uBAAuB,CAsD9D,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
@@ -34,20 +34,11 @@ import { NavigationItemComponent } from '../../../routing/NavigationItem';
34
34
  */
35
35
  const DropdownNavigation = ({ navigation, className, }) => {
36
36
  return (_jsx(Stack, { role: "navigation", direction: "row", align: "center", className: className, style: { gap: 'var(--gap-sm)' }, children: navigation.map((item, idx) => item.routes && item.routes.length > 0 ? (_jsx(DropdownMenu, { trigger: _jsx(Button, { icon: item.icon, children: item.label }), items: item.routes.map((route) => {
37
- const content = route.path ? (route.external ? (_jsx("a", { href: route.path, target: "_blank", rel: "noopener noreferrer", style: {
38
- display: 'flex',
39
- alignItems: 'center',
40
- gap: 'var(--gap-sm)',
41
- width: '100%',
42
- }, children: _jsx(NavigationItemComponent, { route: route }) })) : (_jsx(Link, { path: route.path, style: {
43
- display: 'flex',
44
- alignItems: 'center',
45
- gap: 'var(--gap-sm)',
46
- width: '100%',
47
- }, children: _jsx(NavigationItemComponent, { route: route }) }))) : (_jsx(Stack, { direction: "row", align: "center", style: { gap: 'var(--gap-sm)', width: '100%' }, children: _jsx(NavigationItemComponent, { route: route }) }));
37
+ // NavigationItemComponent already renders a Link/anchor use it directly.
38
+ // External links are handled via the route.external flag inside NavigationItemComponent.
48
39
  return {
49
40
  label: route.label,
50
- children: content,
41
+ children: _jsx(NavigationItemComponent, { route: route }),
51
42
  asChild: !!route.path,
52
43
  };
53
44
  }), contentAlign: "start" }, item.label + idx)) : item.path ? (_jsx(Button, { icon: item.icon, "aria-label": item.label, render: ({ children, ...props }) => (_jsx(Link, { path: item.path, ...props, children: children })), children: item.label }, item.label + idx)) : (_jsx(Button, { icon: item.icon, disabled: true, "aria-label": item.label, children: item.label }, item.label + idx))) }));
@@ -20,7 +20,7 @@ const FloatingLanguageSwitcher = ({ languages, currentLanguage, onLanguageChange
20
20
  return (_jsx(Card, { className: cn('dndev-z-modal', className), style: {
21
21
  position: 'fixed',
22
22
  bottom: 'var(--gap-md)',
23
- right: 'var(--gap-md)',
23
+ insetInlineEnd: 'var(--gap-md)',
24
24
  display: 'flex',
25
25
  alignItems: 'center',
26
26
  gap: 'var(--gap-sm)',
@@ -41,8 +41,6 @@ export interface NotificationsProps {
41
41
  loading?: boolean;
42
42
  /** Callback when notification is dismissed from toast */
43
43
  onNotificationClick?: (notification: NotificationItem) => void;
44
- /** Callback when mark all as read is clicked */
45
- onMarkAllRead?: () => void;
46
44
  /** Callback when dropdown opens */
47
45
  onDropdownOpen?: () => void;
48
46
  /** Maximum number of visible notifications */
@@ -112,6 +110,6 @@ export interface NotificationsProps {
112
110
  * @since 0.0.1
113
111
  * @author AMBROISE PARK Consulting
114
112
  */
115
- export declare const Notifications: ({ notifications, count, loading, onNotificationClick, onMarkAllRead, onDropdownOpen, className, maxVisible, alwaysShow, size, disabled, }: NotificationsProps) => import("react/jsx-runtime").JSX.Element | null;
113
+ export declare const Notifications: ({ notifications, count, loading, onNotificationClick, onDropdownOpen, className, maxVisible, alwaysShow, size, disabled, }: NotificationsProps) => import("react/jsx-runtime").JSX.Element | null;
116
114
  export default Notifications;
117
115
  //# sourceMappingURL=Notifications.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Notifications.d.ts","sourceRoot":"","sources":["../../../../src/components/layout/components/Notifications.tsx"],"names":[],"mappings":"AA+BA;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,6BAA6B;IAC7B,EAAE,EAAE,MAAM,CAAC;IAEX,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IAEd,uCAAuC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,oCAAoC;IACpC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;IAEhD,6CAA6C;IAC7C,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf,8CAA8C;IAC9C,SAAS,CAAC,EAAE,IAAI,CAAC;IAEjB,yBAAyB;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAEtB,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,kCAAkC;IAClC,aAAa,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAEnC,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,kDAAkD;IAClD,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,yDAAyD;IACzD,mBAAmB,CAAC,EAAE,CAAC,YAAY,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAE/D,gDAAgD;IAChD,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAE3B,mCAAmC;IACnC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAE5B,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB,mBAAmB;IACnB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAE1B,wCAAwC;IACxC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAmCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH,eAAO,MAAM,aAAa,GAAI,2IAY3B,kBAAkB,mDA4FpB,CAAC;AAEF,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"Notifications.d.ts","sourceRoot":"","sources":["../../../../src/components/layout/components/Notifications.tsx"],"names":[],"mappings":"AA+BA;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,6BAA6B;IAC7B,EAAE,EAAE,MAAM,CAAC;IAEX,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IAEd,uCAAuC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,oCAAoC;IACpC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;IAEhD,6CAA6C;IAC7C,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf,8CAA8C;IAC9C,SAAS,CAAC,EAAE,IAAI,CAAC;IAEjB,yBAAyB;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAEtB,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,kCAAkC;IAClC,aAAa,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAEnC,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,kDAAkD;IAClD,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,yDAAyD;IACzD,mBAAmB,CAAC,EAAE,CAAC,YAAY,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAE/D,mCAAmC;IACnC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAE5B,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB,mBAAmB;IACnB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAE1B,wCAAwC;IACxC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAmCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH,eAAO,MAAM,aAAa,GAAI,4HAW3B,kBAAkB,mDA+FpB,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -113,7 +113,7 @@ const SIZE_VARIANTS = {
113
113
  * @since 0.0.1
114
114
  * @author AMBROISE PARK Consulting
115
115
  */
116
- export const Notifications = ({ notifications = [], count = 0, loading = false, onNotificationClick, onMarkAllRead, onDropdownOpen, className, maxVisible = 10, alwaysShow = false, size = 'md', disabled = false, }) => {
116
+ export const Notifications = ({ notifications = [], count = 0, loading = false, onNotificationClick, onDropdownOpen, className, maxVisible = 10, alwaysShow = false, size = 'md', disabled = false, }) => {
117
117
  const sizeVariant = SIZE_VARIANTS[size];
118
118
  const shownNotificationIds = useRef(new Set());
119
119
  // Calculate display count (format large numbers)
@@ -159,6 +159,8 @@ export const Notifications = ({ notifications = [], count = 0, loading = false,
159
159
  return (_jsx("div", { className: cn(className), style: { position: 'relative' }, children: _jsx(Button, { disabled: disabled, style: {
160
160
  ...sizeVariant.button,
161
161
  position: 'relative',
162
+ }, onClick: () => {
163
+ onDropdownOpen?.();
162
164
  }, onFocus: (e) => {
163
165
  e.currentTarget.style.outline = '2px solid var(--ring)';
164
166
  e.currentTarget.style.outlineOffset = '2px';
@@ -167,7 +169,7 @@ export const Notifications = ({ notifications = [], count = 0, loading = false,
167
169
  }, "aria-label": `${count} notification${count !== 1 ? 's' : ''}`, icon: Bell, children: displayCount && (_jsx(Stack, { align: "center", justify: "center", style: {
168
170
  position: 'absolute',
169
171
  top: '-0.25rem',
170
- right: '-0.25rem',
172
+ insetInlineEnd: '-0.25rem',
171
173
  backgroundColor: 'var(--destructive)',
172
174
  color: 'var(--destructive-foreground)',
173
175
  borderRadius: 'var(--radius-full)',
@@ -1 +1 @@
1
- {"version":3,"file":"AppBranding.d.ts","sourceRoot":"","sources":["../../../../../src/components/layout/components/header/AppBranding.tsx"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,EAAM,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAMnD,MAAM,WAAW,gBAAgB;IAC/B;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,OAAO,OAAO,CAAC,CAAC;IACjD,8CAA8C;IAC9C,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,WAAW,GAAI,qCAIzB,gBAAgB,4CA2ClB,CAAC;AAEF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"AppBranding.d.ts","sourceRoot":"","sources":["../../../../../src/components/layout/components/header/AppBranding.tsx"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,OAAO,EAAM,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAOnD,MAAM,WAAW,gBAAgB;IAC/B;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,OAAO,OAAO,CAAC,CAAC;IACjD,8CAA8C;IAC9C,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,WAAW,GAAI,qCAIzB,gBAAgB,4CA2ClB,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -13,6 +13,7 @@ import { cn, DISPLAY } from '@donotdev/components';
13
13
  import { useAppConfig } from '@donotdev/core';
14
14
  import { Link } from '../../../../routing/Link';
15
15
  import { AssetResolver } from '../../../../utils/assetResolver';
16
+ import { sanitizeSvg } from '../../../../utils/sanitizeSvg';
16
17
  /**
17
18
  * AppBranding - Unified branding component
18
19
  *
@@ -42,7 +43,7 @@ export const AppBranding = ({ display = DISPLAY.AUTO, linkToHome = true, classNa
42
43
  const svgContent = AssetResolver.getLogoSvgContent();
43
44
  const logoPath = AssetResolver.resolveLogo();
44
45
  const showTitle = display === DISPLAY.FULL || display === DISPLAY.AUTO;
45
- const logo = svgContent ? (_jsx("div", { className: "app-branding-logo", role: "img", "aria-label": displayTitle, dangerouslySetInnerHTML: { __html: svgContent } })) : AssetResolver.assetExists(logoPath) ? (_jsx("img", { src: logoPath, alt: displayTitle, className: "app-branding-logo" })) : null;
46
+ const logo = svgContent ? (_jsx("div", { className: "app-branding-logo", role: "img", "aria-label": displayTitle, dangerouslySetInnerHTML: { __html: sanitizeSvg(svgContent) } })) : AssetResolver.assetExists(logoPath) ? (_jsx("img", { src: logoPath, alt: displayTitle, className: "app-branding-logo" })) : null;
46
47
  const title = showTitle && (_jsx("span", { className: "app-branding-title", "data-display": display, children: displayTitle }));
47
48
  const content = (_jsxs("div", { className: cn('app-branding', className), "data-display": display, children: [logo, title] }));
48
49
  if (linkToHome) {
@@ -1 +1 @@
1
- {"version":3,"file":"AppIcon.d.ts","sourceRoot":"","sources":["../../../../../src/components/layout/components/header/AppIcon.tsx"],"names":[],"mappings":"AAkBA,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrD,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAUD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,OAAO,GAAI,0BAAqC,YAAY,4CA0CxE,CAAC;AAEF,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"AppIcon.d.ts","sourceRoot":"","sources":["../../../../../src/components/layout/components/header/AppIcon.tsx"],"names":[],"mappings":"AAmBA,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrD,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAUD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,OAAO,GAAI,0BAAqC,YAAY,4CA2CxE,CAAC;AAEF,eAAe,OAAO,CAAC"}
@@ -13,6 +13,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
13
13
  import { cn } from '@donotdev/components';
14
14
  import { useAppConfig } from '@donotdev/core';
15
15
  import { AssetResolver } from '../../../../utils/assetResolver';
16
+ import { sanitizeSvg } from '../../../../utils/sanitizeSvg';
16
17
  const SIZE_STYLES = {
17
18
  sm: { width: 'var(--icon-md)', height: 'var(--icon-md)' },
18
19
  md: { width: 'var(--icon-touch)', height: 'var(--icon-touch)' },
@@ -32,7 +33,9 @@ const SIZE_STYLES = {
32
33
  * @author AMBROISE PARK Consulting
33
34
  */
34
35
  export const AppIcon = ({ alt, size = 'header', className }) => {
35
- const resolvedAlt = alt || useAppConfig('name') || useAppConfig('shortName') || 'App';
36
+ const appName = useAppConfig('name');
37
+ const appShortName = useAppConfig('shortName');
38
+ const resolvedAlt = alt || appName || appShortName || 'App';
36
39
  const svgContent = AssetResolver.getLogoSvgContent();
37
40
  const logoPath = AssetResolver.resolveLogo();
38
41
  const sizeStyle = typeof size === 'string' && size in SIZE_STYLES
@@ -45,7 +48,7 @@ export const AppIcon = ({ alt, size = 'header', className }) => {
45
48
  return (_jsx("div", { className: cn('app-icon-header', className), style: {
46
49
  display: 'inline-flex',
47
50
  ...sizeStyle,
48
- }, role: "img", "aria-label": resolvedAlt, dangerouslySetInnerHTML: { __html: svgContent } }));
51
+ }, role: "img", "aria-label": resolvedAlt, dangerouslySetInnerHTML: { __html: sanitizeSvg(svgContent) } }));
49
52
  }
50
53
  // Fallback to img tag if SVG content not available
51
54
  return (_jsx("img", { src: logoPath, alt: resolvedAlt, className: cn(className), style: {
@@ -1 +1 @@
1
- {"version":3,"file":"CacheSettings.d.ts","sourceRoot":"","sources":["../../../../../src/components/layout/components/header/CacheSettings.tsx"],"names":[],"mappings":"AA0BA;;;;;;;;;GASG;AACH,iBAAS,aAAa,4CAqPrB;AAED,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"CacheSettings.d.ts","sourceRoot":"","sources":["../../../../../src/components/layout/components/header/CacheSettings.tsx"],"names":[],"mappings":"AA0BA;;;;;;;;;GASG;AACH,iBAAS,aAAa,4CAuPrB;AAED,eAAe,aAAa,CAAC"}
@@ -97,7 +97,9 @@ function CacheSettings() {
97
97
  tx.executeSql('SELECT name FROM sqlite_master WHERE type="table"', [], (tx, results) => {
98
98
  for (let i = 0; i < results.rows.length; i++) {
99
99
  const tableName = results.rows.item(i).name;
100
- tx.executeSql(`DROP TABLE IF EXISTS ${tableName}`);
100
+ if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(tableName)) {
101
+ tx.executeSql(`DROP TABLE IF EXISTS ${tableName}`);
102
+ }
101
103
  }
102
104
  });
103
105
  });
@@ -13,6 +13,12 @@ export interface HeaderNavigationProps {
13
13
  * @default 'auto'
14
14
  */
15
15
  display?: (typeof DISPLAY)[keyof typeof DISPLAY];
16
+ /**
17
+ * Single-item mode: render one route as a standalone Button.
18
+ * Resolves label, icon, and active state from the navigation store.
19
+ * Renders null if the path is not found or inaccessible.
20
+ */
21
+ path?: string;
16
22
  }
17
23
  /**
18
24
  * HeaderNavigation - DISPLAY-aware adaptive navigation component
@@ -1 +1 @@
1
- {"version":3,"file":"HeaderNavigation.d.ts","sourceRoot":"","sources":["../../../../../src/components/layout/components/header/HeaderNavigation.tsx"],"names":[],"mappings":"AAoBA,OAAO,EACL,OAAO,EAIR,MAAM,sBAAsB,CAAC;AAQ9B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C,MAAM,WAAW,qBAAqB;IACpC,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4BAA4B;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,OAAO,OAAO,CAAC,CAAC;CAClD;AAED;;;;;;;;;;;GAWG;AACH,QAAA,MAAM,gBAAgB,EAAE,aAAa,CAAC,qBAAqB,CAkD1D,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"HeaderNavigation.d.ts","sourceRoot":"","sources":["../../../../../src/components/layout/components/header/HeaderNavigation.tsx"],"names":[],"mappings":"AAsBA,OAAO,EACL,OAAO,EAIR,MAAM,sBAAsB,CAAC;AAU9B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C,MAAM,WAAW,qBAAqB;IACpC,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4BAA4B;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,OAAO,OAAO,CAAC,CAAC;IACjD;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;GAWG;AACH,QAAA,MAAM,gBAAgB,EAAE,aAAa,CAAC,qBAAqB,CAwE1D,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -16,12 +16,15 @@ import { jsx as _jsx } from "react/jsx-runtime";
16
16
  * @author AMBROISE PARK Consulting
17
17
  */
18
18
  import { MoreHorizontal } from 'lucide-react';
19
+ import { Link as LinkIcon } from 'lucide-react';
19
20
  import { DISPLAY, DropdownMenu, Button, } from '@donotdev/components';
20
21
  import { cn } from '@donotdev/components';
21
22
  import { useBreakpoint, useTranslation } from '@donotdev/core';
23
+ import { Link } from '../../../../routing/Link';
24
+ import { Icon } from '../../../common/icon';
22
25
  import { DnDevNavigationMenu } from '../../../../routing/DnDevNavigationMenu';
23
26
  import { NavigationItemComponent } from '../../../../routing/NavigationItem';
24
- import { useNavigationItems } from '../../../../routing/useNavigation';
27
+ import { useNavigationItems, useNavigationRoute } from '../../../../routing/useNavigation';
25
28
  /**
26
29
  * HeaderNavigation - DISPLAY-aware adaptive navigation component
27
30
  *
@@ -34,11 +37,18 @@ import { useNavigationItems } from '../../../../routing/useNavigation';
34
37
  * @since 0.0.1
35
38
  * @author AMBROISE PARK Consulting
36
39
  */
37
- const HeaderNavigation = ({ className = '', showIcons = true, display = DISPLAY.AUTO, }) => {
40
+ const HeaderNavigation = ({ className = '', showIcons = true, display = DISPLAY.AUTO, path, }) => {
38
41
  const { t } = useTranslation('dndev');
39
42
  const isMobile = useBreakpoint('isMobile');
40
43
  const isTablet = useBreakpoint('isTablet');
41
44
  const navigationItems = useNavigationItems();
45
+ const singleRoute = useNavigationRoute(path ?? '');
46
+ // Single-item mode — render one route as a Button link.
47
+ if (path) {
48
+ if (!singleRoute)
49
+ return null;
50
+ return (_jsx(Button, { variant: "ghost", display: display, icon: showIcons ? _jsx(Icon, { icon: singleRoute.icon, fallback: LinkIcon }) : undefined, className: className, render: ({ children, ...props }) => (_jsx(Link, { path: singleRoute.path, ...props, children: children })), children: singleRoute.label }));
51
+ }
42
52
  const effectiveDisplay = display === DISPLAY.AUTO
43
53
  ? isMobile || isTablet
44
54
  ? DISPLAY.COMPACT
@@ -1 +1 @@
1
- {"version":3,"file":"LicenseWatermark.d.ts","sourceRoot":"","sources":["../../../src/components/license/LicenseWatermark.tsx"],"names":[],"mappings":"AAsBA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,gBAAgB,mDAsG/B"}
1
+ {"version":3,"file":"LicenseWatermark.d.ts","sourceRoot":"","sources":["../../../src/components/license/LicenseWatermark.tsx"],"names":[],"mappings":"AAsBA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,gBAAgB,mDAwG/B"}
@@ -41,6 +41,8 @@ import { watermarkSvg } from './watermarkData';
41
41
  */
42
42
  export function LicenseWatermark() {
43
43
  const license = checkLicense();
44
+ /** Production console.warn is intentional — alerts unlicensed deployments.
45
+ * This is a license enforcement mechanism, not a debug log. */
44
46
  useEffect(() => {
45
47
  if (!license.isValid) {
46
48
  // Console warnings
@@ -61,7 +63,7 @@ export function LicenseWatermark() {
61
63
  }
62
64
  return (_jsxs("a", { href: "https://donotdev.com/pricing", target: "_blank", rel: "noopener noreferrer", style: {
63
65
  position: 'fixed',
64
- right: '20px',
66
+ insetInlineEnd: '20px',
65
67
  top: '50%',
66
68
  transform: 'translateY(-50%)',
67
69
  zIndex: 9999,
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @fileoverview UI CrudCard wrapper
3
+ * @description Thin wrapper around @donotdev/crud CrudCard that adds Link routing.
4
+ * CrudCard (crud) is platform-agnostic; this wrapper adds web navigation via Link.
5
+ *
6
+ * @version 0.2.0
7
+ * @since 0.0.1
8
+ * @author AMBROISE PARK Consulting
9
+ */
10
+ import type { CrudCardProps } from '@donotdev/core';
11
+ /**
12
+ * CrudCard with Link wrapping for web navigation.
13
+ * When detailHref is provided, wraps the card in a Link for a11y/SEO.
14
+ */
15
+ export declare function CrudCard({ detailHref, onClick, ...rest }: CrudCardProps): import("react/jsx-runtime").JSX.Element;
16
+ export default CrudCard;
17
+ //# sourceMappingURL=CrudCardLink.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CrudCardLink.d.ts","sourceRoot":"","sources":["../../../src/crud/components/CrudCardLink.tsx"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAIpD;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,EACvB,UAAU,EACV,OAAO,EACP,GAAG,IAAI,EACR,EAAE,aAAa,2CAqBf;AAED,eAAe,QAAQ,CAAC"}
@@ -0,0 +1,17 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { CrudCard as BaseCrudCard } from '@donotdev/crud';
4
+ import { Link } from '../../routing';
5
+ /**
6
+ * CrudCard with Link wrapping for web navigation.
7
+ * When detailHref is provided, wraps the card in a Link for a11y/SEO.
8
+ */
9
+ export function CrudCard({ detailHref, onClick, ...rest }) {
10
+ // When detailHref is set, Link handles navigation — don't pass onClick to inner card
11
+ const card = (_jsx(BaseCrudCard, { ...rest, onClick: detailHref ? undefined : onClick }));
12
+ if (detailHref) {
13
+ return (_jsx(Link, { path: detailHref, "aria-label": rest.item?.id ? `View ${rest.item.id}` : undefined, children: card }));
14
+ }
15
+ return card;
16
+ }
17
+ export default CrudCard;
@@ -1 +1 @@
1
- {"version":3,"file":"EntityCardList.d.ts","sourceRoot":"","sources":["../../../src/crud/components/EntityCardList.tsx"],"names":[],"mappings":"AAyCA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAEpC;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,QAAQ,EACR,OAAO,EACP,IAAmB,EACnB,SAA0B,EAAE,2BAA2B;AACvD,MAAM,EACN,WAAmB,GACpB,EAAE,mBAAmB,2CA6RrB"}
1
+ {"version":3,"file":"EntityCardList.d.ts","sourceRoot":"","sources":["../../../src/crud/components/EntityCardList.tsx"],"names":[],"mappings":"AAsCA,OAAO,KAAK,EAAE,mBAAmB,EAAgB,MAAM,gBAAgB,CAAC;AAIxE,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAEpC;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,QAAQ,EACR,OAAO,EACP,IAAmB,EACnB,SAA0B,EAAE,2BAA2B;AACvD,MAAM,EACN,WAAmB,GACpB,EAAE,mBAAmB,2CAqMrB"}