@contractspec/lib.design-system 4.3.0 → 4.4.1

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 (151) hide show
  1. package/README.md +53 -17
  2. package/dist/browser/components/data-view/DataViewRenderer.js +1 -1
  3. package/dist/browser/components/data-view/collection.js +1 -1
  4. package/dist/browser/components/forms/controls/Select.js +1 -1
  5. package/dist/browser/components/object-reference/DefaultObjectReferenceDetail.js +1 -0
  6. package/dist/browser/components/object-reference/DefaultObjectReferenceParts.js +1 -1
  7. package/dist/browser/components/object-reference/DefaultObjectReferenceProperty.js +1 -0
  8. package/dist/browser/components/object-reference/ObjectReferenceHandler.js +1 -1
  9. package/dist/browser/components/object-reference/ObjectReferencePanel.js +1 -0
  10. package/dist/browser/components/object-reference/ReferenceIcon.js +1 -1
  11. package/dist/browser/components/object-reference/actions.js +1 -1
  12. package/dist/browser/components/object-reference/index.js +1 -1
  13. package/dist/browser/components/object-reference/runtime.js +1 -1
  14. package/dist/browser/components/object-reference/url-safety.js +1 -0
  15. package/dist/browser/components/object-reference/useObjectReferenceController.js +1 -1
  16. package/dist/browser/components/organisms/Header.js +1 -1
  17. package/dist/browser/components/organisms/MarketingHeader.js +1 -1
  18. package/dist/browser/components/organisms/MarketingHeaderMobile.js +1 -1
  19. package/dist/browser/components/overlays/AdaptivePanel.js +1 -0
  20. package/dist/browser/components/overlays/index.js +1 -0
  21. package/dist/browser/components/shell/AppShell.js +1 -1
  22. package/dist/browser/components/shell/ShellNotifications.js +1 -0
  23. package/dist/browser/components/shell/ShellSidebar.js +1 -1
  24. package/dist/browser/components/shell/index.js +1 -1
  25. package/dist/browser/components/shell/policy.js +1 -0
  26. package/dist/browser/i18n/translation.js +1 -1
  27. package/dist/browser/index.js +1 -1
  28. package/dist/browser/renderers/form-contract/phone-country-control.js +1 -0
  29. package/dist/browser/renderers/form-contract/phone-country-utils.js +1 -0
  30. package/dist/browser/renderers/form-contract/phone-field.js +1 -0
  31. package/dist/browser/renderers/form-contract/phone-utils.js +1 -0
  32. package/dist/browser/renderers/form-contract/rich-fields.js +1 -1
  33. package/dist/browser/renderers/form-contract/values.js +1 -1
  34. package/dist/components/data-view/DataViewRenderer.d.ts +5 -2
  35. package/dist/components/data-view/DataViewRenderer.js +1 -1
  36. package/dist/components/data-view/DataViewRenderer.native.d.ts +5 -2
  37. package/dist/components/data-view/DataViewTable.d.ts +1 -1
  38. package/dist/components/data-view/DataViewTable.native.d.ts +1 -1
  39. package/dist/components/data-view/collection.d.ts +9 -1
  40. package/dist/components/data-view/collection.js +1 -1
  41. package/dist/components/forms/controls/Select.d.ts +1 -1
  42. package/dist/components/forms/controls/Select.js +1 -1
  43. package/dist/components/legal/molecules/LegalTOC.d.ts +1 -1
  44. package/dist/components/marketing/MarketingCardsSection.d.ts +1 -1
  45. package/dist/components/molecules/StatusChip.d.ts +1 -1
  46. package/dist/components/object-reference/DefaultObjectReferenceDetail.d.ts +10 -0
  47. package/dist/components/object-reference/DefaultObjectReferenceDetail.js +1 -0
  48. package/dist/components/object-reference/DefaultObjectReferenceParts.d.ts +0 -3
  49. package/dist/components/object-reference/DefaultObjectReferenceParts.js +1 -1
  50. package/dist/components/object-reference/DefaultObjectReferenceParts.native.d.ts +6 -3
  51. package/dist/components/object-reference/DefaultObjectReferenceProperty.d.ts +13 -0
  52. package/dist/components/object-reference/DefaultObjectReferenceProperty.js +1 -0
  53. package/dist/components/object-reference/ObjectReferenceHandler.d.ts +1 -1
  54. package/dist/components/object-reference/ObjectReferenceHandler.js +1 -1
  55. package/dist/components/object-reference/ObjectReferenceHandler.native.d.ts +1 -1
  56. package/dist/components/object-reference/ObjectReferencePanel.d.ts +18 -0
  57. package/dist/components/object-reference/ObjectReferencePanel.js +1 -0
  58. package/dist/components/object-reference/ReferenceIcon.js +1 -1
  59. package/dist/components/object-reference/actions.d.ts +7 -2
  60. package/dist/components/object-reference/actions.js +1 -1
  61. package/dist/components/object-reference/index.d.ts +4 -2
  62. package/dist/components/object-reference/index.js +1 -1
  63. package/dist/components/object-reference/index.native.d.ts +2 -2
  64. package/dist/components/object-reference/runtime.d.ts +2 -1
  65. package/dist/components/object-reference/runtime.js +1 -1
  66. package/dist/components/object-reference/types.d.ts +36 -3
  67. package/dist/components/object-reference/url-safety.d.ts +2 -0
  68. package/dist/components/object-reference/url-safety.js +1 -0
  69. package/dist/components/object-reference/useObjectReferenceController.d.ts +5 -2
  70. package/dist/components/object-reference/useObjectReferenceController.js +1 -1
  71. package/dist/components/organisms/Header.js +1 -1
  72. package/dist/components/organisms/MarketingHeader.js +1 -1
  73. package/dist/components/organisms/MarketingHeaderMobile.js +1 -1
  74. package/dist/components/overlays/AdaptivePanel.d.ts +26 -0
  75. package/dist/components/overlays/AdaptivePanel.js +1 -0
  76. package/dist/components/overlays/index.d.ts +1 -0
  77. package/dist/components/overlays/index.js +1 -0
  78. package/dist/components/shell/AppShell.d.ts +1 -1
  79. package/dist/components/shell/AppShell.js +1 -1
  80. package/dist/components/shell/AppShell.native.d.ts +1 -1
  81. package/dist/components/shell/AppShell.types.d.ts +2 -1
  82. package/dist/components/shell/ShellNotifications.d.ts +5 -0
  83. package/dist/components/shell/ShellNotifications.js +1 -0
  84. package/dist/components/shell/ShellNotifications.native.d.ts +5 -0
  85. package/dist/components/shell/ShellSidebar.d.ts +2 -1
  86. package/dist/components/shell/ShellSidebar.js +1 -1
  87. package/dist/components/shell/index.d.ts +4 -1
  88. package/dist/components/shell/index.js +1 -1
  89. package/dist/components/shell/index.native.d.ts +2 -1
  90. package/dist/components/shell/policy.d.ts +15 -0
  91. package/dist/components/shell/policy.js +1 -0
  92. package/dist/components/shell/types.d.ts +50 -0
  93. package/dist/i18n/translation.d.ts +6 -1
  94. package/dist/i18n/translation.js +1 -1
  95. package/dist/index.d.ts +2 -1
  96. package/dist/index.js +1 -1
  97. package/dist/native/components/data-view/DataViewRenderer.js +1 -1
  98. package/dist/native/components/data-view/DataViewRenderer.native.js +1 -1
  99. package/dist/native/components/data-view/collection.js +1 -1
  100. package/dist/native/components/forms/controls/Select.js +1 -1
  101. package/dist/native/components/object-reference/DefaultObjectReferenceDetail.js +1 -0
  102. package/dist/native/components/object-reference/DefaultObjectReferenceParts.js +1 -1
  103. package/dist/native/components/object-reference/DefaultObjectReferenceParts.native.js +1 -1
  104. package/dist/native/components/object-reference/DefaultObjectReferenceProperty.js +1 -0
  105. package/dist/native/components/object-reference/ObjectReferenceHandler.js +1 -1
  106. package/dist/native/components/object-reference/ObjectReferenceHandler.native.js +1 -1
  107. package/dist/native/components/object-reference/ObjectReferencePanel.js +1 -0
  108. package/dist/native/components/object-reference/ReferenceIcon.js +1 -1
  109. package/dist/native/components/object-reference/actions.js +1 -1
  110. package/dist/native/components/object-reference/index.js +1 -1
  111. package/dist/native/components/object-reference/index.native.js +1 -1
  112. package/dist/native/components/object-reference/runtime.js +1 -1
  113. package/dist/native/components/object-reference/url-safety.js +1 -0
  114. package/dist/native/components/object-reference/useObjectReferenceController.js +1 -1
  115. package/dist/native/components/organisms/Header.js +1 -1
  116. package/dist/native/components/organisms/MarketingHeader.js +1 -1
  117. package/dist/native/components/organisms/MarketingHeaderMobile.js +1 -1
  118. package/dist/native/components/overlays/AdaptivePanel.js +1 -0
  119. package/dist/native/components/overlays/index.js +1 -0
  120. package/dist/native/components/shell/AppShell.js +1 -1
  121. package/dist/native/components/shell/AppShell.native.js +1 -1
  122. package/dist/native/components/shell/ShellNotifications.js +1 -0
  123. package/dist/native/components/shell/ShellNotifications.native.js +1 -0
  124. package/dist/native/components/shell/ShellSidebar.js +1 -1
  125. package/dist/native/components/shell/index.js +1 -1
  126. package/dist/native/components/shell/index.native.js +1 -1
  127. package/dist/native/components/shell/policy.js +1 -0
  128. package/dist/native/i18n/translation.js +1 -1
  129. package/dist/native/index.js +1 -1
  130. package/dist/native/renderers/form-contract/phone-country-control.js +1 -0
  131. package/dist/native/renderers/form-contract/phone-country-control.native.js +1 -0
  132. package/dist/native/renderers/form-contract/phone-country-utils.js +1 -0
  133. package/dist/native/renderers/form-contract/phone-field.js +1 -0
  134. package/dist/native/renderers/form-contract/phone-utils.js +1 -0
  135. package/dist/native/renderers/form-contract/rich-fields.js +1 -1
  136. package/dist/native/renderers/form-contract/values.js +1 -1
  137. package/dist/renderers/form-contract/phone-country-control.d.ts +18 -0
  138. package/dist/renderers/form-contract/phone-country-control.js +1 -0
  139. package/dist/renderers/form-contract/phone-country-control.native.d.ts +18 -0
  140. package/dist/renderers/form-contract/phone-country-utils.d.ts +9 -0
  141. package/dist/renderers/form-contract/phone-country-utils.js +1 -0
  142. package/dist/renderers/form-contract/phone-field.d.ts +18 -0
  143. package/dist/renderers/form-contract/phone-field.js +1 -0
  144. package/dist/renderers/form-contract/phone-utils.d.ts +3 -0
  145. package/dist/renderers/form-contract/phone-utils.js +1 -0
  146. package/dist/renderers/form-contract/rich-fields.d.ts +2 -12
  147. package/dist/renderers/form-contract/rich-fields.js +1 -1
  148. package/dist/renderers/form-contract/values.d.ts +1 -0
  149. package/dist/renderers/form-contract/values.js +1 -1
  150. package/dist/theme/variants.d.ts +1 -1
  151. package/package.json +187 -9
@@ -1 +1 @@
1
- import*as q from"react";import{createDefaultObjectReferenceActions as $}from"./actions";import{executeObjectReferenceAction as D}from"./runtime";export function useObjectReferenceController({reference:k,actions:F,defaultOpen:W=!1,open:G,onOpenChange:I,actionHandlers:J,onAction:K,onActionError:L,copyText:M,copyHandler:N,openHref:P,defaultCopy:Q,defaultOpenHref:S}){const[X,Y]=q.useState(W),V=G!==void 0,w=G??X,z=q.useMemo(()=>F??$(k),[F,k]),B=q.useCallback((m)=>{if(!V)Y(m);I?.(m)},[V,I]),Z=q.useMemo(()=>({reference:k,actions:z,open:w,setOpen:B}),[k,z,w,B]),_=q.useCallback((m)=>{if(m.disabled)return;D({reference:k,action:m,source:"action"},{actionHandlers:J,copyText:M,copyHandler:N,openHref:P,onAction:K,onActionError:L,defaultCopy:Q,defaultOpenHref:S})},[J,N,M,Q,S,K,L,P,k]);return{context:Z,resolvedActions:z,resolvedOpen:w,runAction:_,setOpen:B}}
1
+ import*as q from"react";import{createDefaultObjectReferenceActions as v}from"./actions";import{executeObjectReferenceAction as x}from"./runtime";export function useObjectReferenceController({reference:k,actions:I,defaultOpen:$=!1,open:J,onOpenChange:K,actionHandlers:L,onAction:M,onActionError:N,copyText:P,copyHandler:Q,openHref:S,openTarget:B,defaultCopy:V,defaultOpenTarget:W,defaultOpenHref:X}){const[U,b]=q.useState($),Y=J!==void 0,F=J??U,G=q.useMemo(()=>I??k.actions??v(k),[I,k]),w=q.useCallback((m)=>{if(!Y)b(m);K?.(m)},[Y,K]),j=q.useMemo(()=>({reference:k,actions:G,open:F,setOpen:w}),[k,G,F,w]),z=q.useCallback((m,Z,E="action")=>{if(Z.disabled)return;x({reference:m,action:Z,source:E},{actionHandlers:L,copyText:P,copyHandler:Q,openHref:S,onAction:M,onActionError:N,defaultOpenTarget:_(B,m.openTarget,W),defaultCopy:V,defaultOpenHref:X})},[L,Q,P,V,W,X,M,N,B,S]),D=q.useCallback((m)=>{z(k,m)},[k,z]),h=q.useCallback(()=>{const m=_(B,k.openTarget);if(m==="new-page"&&k.href){z(k,{id:"open-detail",label:"Open details",href:k.href,openTarget:m,iconKey:"external-link"},"trigger");return}w(!0)},[B,k,z,w]);return{context:j,openDetail:h,resolvedActions:G,resolvedOpen:F,runAction:D,runReferenceAction:z,setOpen:w}}function _(...k){return k.find(Boolean)??"same-page"}
@@ -1 +1 @@
1
- import{jsx as z,jsxs as G,Fragment as U}from"react/jsx-runtime";import{Separator as X}from"@contractspec/lib.ui-kit-web/ui/separator";import{Sheet as Y,SheetContent as Z,SheetTitle as $,SheetTrigger as q}from"@contractspec/lib.ui-kit-web/ui/sheet";import{cn as P}from"@contractspec/lib.ui-kit-web/ui/utils";import{cva as Q}from"class-variance-authority";import{Menu as C}from"lucide-react";import{Button as D}from"../atoms/Button";import{ButtonLink as F}from"../atoms/ButtonLink";import{NavMain as A}from"../molecules/NavMain";import{NavUser as R}from"../molecules/NavUser";import{AppSidebar as L}from"./AppSidebar";const T=Q("hidden items-center justify-between gap-4 md:flex",{variants:{density:{compact:"px-3 py-1",comfortable:"px-4 py-2"}},defaultVariants:{density:"comfortable"}});const V=Q("flex items-center justify-between md:hidden",{variants:{density:{compact:"px-2 py-1",comfortable:"px-3 py-2"}},defaultVariants:{density:"comfortable"}});export function DesktopHeader({logo:I,nav:K,userMenu:E,cta:J,className:O,density:W}){return G("header",{className:P(T({density:W}),O),children:[G("div",{className:"flex items-center gap-4",children:[I,z(X,{orientation:"vertical",className:"h-6"}),z(A,{items:K})]}),G("div",{className:"flex items-center gap-2",children:[J&&z(F,{variant:J.variant,href:J.href,children:J.label}),E&&z(R,{...E})]})]})}export function MobileHeader({logo:I,userMenu:K,mobileSidebar:E,className:J,density:O}){return G("header",{className:P(V({density:O}),J),children:[G(Y,{children:[z(q,{asChild:!0,children:z(D,{variant:"ghost",size:"icon","aria-label":"Open menu",children:z(C,{className:"h-5 w-5"})})}),G(Z,{side:"left",className:"w-[300px] p-0",children:[z($,{className:"sr-only",children:"Menu"}),E?z(L,{sections:E.sections,top:E.top,bottom:E.bottom,className:"h-svh"}):z("div",{className:"p-4",children:"No sidebar configured"})]})]}),z("div",{className:"flex-1 px-2",children:I}),z("div",{className:"flex items-center gap-2",children:K&&z(R,{...K})})]})}export function Header(I){return G(U,{children:[z(MobileHeader,{...I}),z(DesktopHeader,{...I})]})}
1
+ import{jsx as z,jsxs as I,Fragment as A}from"react/jsx-runtime";import{Separator as Z}from"@contractspec/lib.ui-kit-web/ui/separator";import{cn as T}from"@contractspec/lib.ui-kit-web/ui/utils";import{cva as W}from"class-variance-authority";import{Menu as $}from"lucide-react";import*as q from"react";import{Button as D}from"../atoms/Button";import{ButtonLink as F}from"../atoms/ButtonLink";import{NavMain as O}from"../molecules/NavMain";import{NavUser as X}from"../molecules/NavUser";import{AdaptivePanel as P}from"../overlays";import{AppSidebar as R}from"./AppSidebar";const L=W("hidden items-center justify-between gap-4 md:flex",{variants:{density:{compact:"px-3 py-1",comfortable:"px-4 py-2"}},defaultVariants:{density:"comfortable"}});const V=W("flex items-center justify-between md:hidden",{variants:{density:{compact:"px-2 py-1",comfortable:"px-3 py-2"}},defaultVariants:{density:"comfortable"}});export function DesktopHeader({logo:E,nav:J,userMenu:C,cta:G,className:K,density:Q}){return I("header",{className:T(L({density:Q}),K),children:[I("div",{className:"flex items-center gap-4",children:[E,z(Z,{orientation:"vertical",className:"h-6"}),z(O,{items:J})]}),I("div",{className:"flex items-center gap-2",children:[G&&z(F,{variant:G.variant,href:G.href,children:G.label}),C&&z(X,{...C})]})]})}export function MobileHeader({logo:E,userMenu:J,mobileSidebar:C,className:G,density:K}){const[Q,Y]=q.useState(!1);return I("header",{className:T(V({density:K}),G),children:[z(P,{mode:"drawer",drawerDirection:"left",open:Q,onOpenChange:Y,trigger:z(D,{variant:"ghost",size:"icon","aria-label":"Open menu",children:z($,{className:"h-5 w-5"})}),title:"Menu",headerClassName:"sr-only",className:"w-[300px] p-0",children:C?z(R,{sections:C.sections,top:C.top,bottom:C.bottom,className:"h-svh"}):z("div",{className:"p-4",children:"No sidebar configured"})}),z("div",{className:"flex-1 px-2",children:E}),z("div",{className:"flex items-center gap-2",children:J&&z(X,{...J})})]})}export function Header(E){return I(A,{children:[z(MobileHeader,{...E}),z(DesktopHeader,{...E})]})}
@@ -1 +1 @@
1
- import{jsx as z,jsxs as J,Fragment as I}from"react/jsx-runtime";import{NavigationMenu as M,NavigationMenuContent as L,NavigationMenuItem as C,NavigationMenuLink as P,NavigationMenuList as k,NavigationMenuTrigger as N}from"@contractspec/lib.ui-kit-web/ui/navigation-menu";import{Separator as d}from"@contractspec/lib.ui-kit-web/ui/separator";import{Sheet as p,SheetContent as S,SheetHeader as v,SheetTrigger as h}from"@contractspec/lib.ui-kit-web/ui/sheet";import{Box as Y,HStack as W,VStack as b}from"@contractspec/lib.ui-kit-web/ui/stack";import{Text as q}from"@contractspec/lib.ui-kit-web/ui/text";import{cn as D}from"@contractspec/lib.ui-kit-web/ui/utils";import{cva as u}from"class-variance-authority";import{Menu as f}from"lucide-react";import*as g from"react";import{Button as y}from"../atoms/Button";import{ButtonLink as F}from"../atoms/ButtonLink";import{CommandSearchTrigger as U}from"../molecules/CommandSearchTrigger";import{LangSwitchDropdown as _}from"../molecules/LangSwitchDropdown";import{MobileNavMenu as l}from"../molecules/MobileNavMenu";import{NavItemCard as w}from"../molecules/NavItemCard";import{NavUser as j}from"../molecules/NavUser";const x=u("flex items-center justify-between gap-4",{variants:{density:{compact:"px-3 py-2",comfortable:"px-4 py-3"}},defaultVariants:{density:"comfortable"}});export function MarketingHeader({logo:V,nav:X=[],navLinkClassName:Z,userMenu:$,cta:A,className:H,density:B,right:O,commandPaletteGroups:K,langSwitchProps:Q}){const[T,G]=g.useState(!1);return z(W,{as:"header",className:D("sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur-xs supports-backdrop-filter:bg-background/60",H),children:J(W,{className:D("mx-auto w-full max-w-7xl items-center justify-center",x({density:B})),children:[z(b,{className:"flex items-center gap-2 md:hidden",children:J(p,{open:T,onOpenChange:G,children:[z(h,{asChild:!0,children:z(y,{variant:"ghost",size:"icon","aria-label":"Open menu",children:z(f,{className:"h-5 w-5"})})}),J(S,{side:"left",className:"w-[320px] p-4",children:[!!K?.length&&z(v,{children:z(U,{groups:K})}),A&&z(b,{className:"mb-3",children:z(F,{variant:A.variant,size:A.size,href:A.href,onClick:A.onClick,children:z(q,{children:A.label})})}),z(l,{items:X})]})]})}),V,z(W,{className:"hidden items-center gap-4 md:flex",children:X.length>0&&J(I,{children:[z(d,{orientation:"vertical",className:"h-6"}),z(M,{className:"hidden md:flex",children:z(k,{children:X.map((E)=>z(C,{children:E.items&&E.items.length>0?J(I,{children:[z(N,{className:Z,children:E.label}),z(L,{children:z("div",{className:"grid w-[760px] grid-cols-3 gap-3 p-3",children:E.items.map((R)=>z(w,{item:R},R.href))})})]}):z(P,{className:Z,href:E.href||"#",children:E.label})},String(E.key??E.href??E.label)))})})]})}),J(W,{className:"flex items-center gap-2",children:[!!K?.length&&z(Y,{className:"hidden items-center gap-2 md:flex",children:z(U,{groups:K})}),Q?.options?.length>1&&z(_,{value:Q.value,onChange:Q.onChange,options:Q.options}),O&&z(Y,{className:"hidden md:flex",children:O}),A&&z(Y,{className:"hidden md:flex",children:z(F,{variant:A.variant,size:A.size,href:A.href,onClick:A.onClick,children:z(q,{children:A.label})})}),$&&z(j,{...$})]})]})})}
1
+ import{jsx as z,jsxs as K,Fragment as I}from"react/jsx-runtime";import{NavigationMenu as M,NavigationMenuContent as C,NavigationMenuItem as L,NavigationMenuLink as k,NavigationMenuList as P,NavigationMenuTrigger as N}from"@contractspec/lib.ui-kit-web/ui/navigation-menu";import{Separator as d}from"@contractspec/lib.ui-kit-web/ui/separator";import{Box as Z,HStack as X,VStack as b}from"@contractspec/lib.ui-kit-web/ui/stack";import{Text as q}from"@contractspec/lib.ui-kit-web/ui/text";import{cn as D}from"@contractspec/lib.ui-kit-web/ui/utils";import{cva as S}from"class-variance-authority";import{Menu as p}from"lucide-react";import*as h from"react";import{Button as v}from"../atoms/Button";import{ButtonLink as F}from"../atoms/ButtonLink";import{CommandSearchTrigger as U}from"../molecules/CommandSearchTrigger";import{LangSwitchDropdown as g}from"../molecules/LangSwitchDropdown";import{MobileNavMenu as u}from"../molecules/MobileNavMenu";import{NavItemCard as f}from"../molecules/NavItemCard";import{NavUser as y}from"../molecules/NavUser";import{AdaptivePanel as _}from"../overlays";const j=S("flex items-center justify-between gap-4",{variants:{density:{compact:"px-3 py-2",comfortable:"px-4 py-3"}},defaultVariants:{density:"comfortable"}});export function MarketingHeader({logo:V,nav:Y=[],navLinkClassName:$,userMenu:A,cta:E,className:H,density:B,right:O,commandPaletteGroups:Q,langSwitchProps:W}){const[T,G]=h.useState(!1);return z(X,{as:"header",className:D("sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur-xs supports-backdrop-filter:bg-background/60",H),children:K(X,{className:D("mx-auto w-full max-w-7xl items-center justify-center",j({density:B})),children:[z(b,{className:"flex items-center gap-2 md:hidden",children:z(_,{mode:"drawer",drawerDirection:"left",open:T,onOpenChange:G,trigger:z(v,{variant:"ghost",size:"icon","aria-label":"Open menu",children:z(p,{className:"h-5 w-5"})}),title:"Menu",className:"w-[320px]",children:K("div",{className:"px-4 pb-4",children:[!!Q?.length&&z("div",{className:"mb-3",children:z(U,{groups:Q})}),E&&z(b,{className:"mb-3",children:z(F,{variant:E.variant,size:E.size,href:E.href,onClick:E.onClick,children:z(q,{children:E.label})})}),z(u,{items:Y})]})})}),V,z(X,{className:"hidden items-center gap-4 md:flex",children:Y.length>0&&K(I,{children:[z(d,{orientation:"vertical",className:"h-6"}),z(M,{className:"hidden md:flex",children:z(P,{children:Y.map((J)=>z(L,{children:J.items&&J.items.length>0?K(I,{children:[z(N,{className:$,children:J.label}),z(C,{children:z("div",{className:"grid w-[760px] grid-cols-3 gap-3 p-3",children:J.items.map((R)=>z(f,{item:R},R.href))})})]}):z(k,{className:$,href:J.href||"#",children:J.label})},String(J.key??J.href??J.label)))})})]})}),K(X,{className:"flex items-center gap-2",children:[!!Q?.length&&z(Z,{className:"hidden items-center gap-2 md:flex",children:z(U,{groups:Q})}),W?.options?.length>1&&z(g,{value:W.value,onChange:W.onChange,options:W.options}),O&&z(Z,{className:"hidden md:flex",children:O}),E&&z(Z,{className:"hidden md:flex",children:z(F,{variant:E.variant,size:E.size,href:E.href,onClick:E.onClick,children:z(q,{children:E.label})})}),A&&z(y,{...A})]})]})})}
@@ -1 +1 @@
1
- import{jsx as q,jsxs as z}from"react/jsx-runtime";import{Sheet as X,SheetContent as Y,SheetFooter as Z,SheetHeader as $,SheetTitle as k,SheetTrigger as B}from"@contractspec/lib.ui-kit-web/ui/sheet";import{VStack as F}from"@contractspec/lib.ui-kit-web/ui/stack";import{cn as H}from"@contractspec/lib.ui-kit-web/ui/utils";import{Menu as O}from"lucide-react";import*as R from"react";import{Button as V}from"../atoms/Button";import{CommandSearchTrigger as b}from"../molecules/CommandSearchTrigger";import{LangSwitchDropdown as D}from"../molecules/LangSwitchDropdown";import{MobileNavMenu as L}from"../molecules/MobileNavMenu";export function MarketingHeaderMobile({logo:I,nav:J=[],className:K,right:Q,commandPaletteGroups:E,langSwitchProps:A}){const[U,W]=R.useState(!1);return q("div",{className:H("w-full border-b bg-background/95 backdrop-blur-xs supports-backdrop-filter:bg-background/60 md:hidden",K),children:z("div",{className:"mx-auto flex w-full max-w-7xl items-center justify-between px-3 py-2",children:[z("div",{className:"flex items-center gap-2",children:[z(X,{open:U,onOpenChange:W,children:[q(B,{asChild:!0,children:q(V,{variant:"ghost",size:"icon","aria-label":"Open menu",children:q(O,{className:"h-5 w-5"})})}),z(Y,{side:"left",className:"w-[320px] p-4",children:[z($,{children:[q(k,{children:"Menu"}),!!E?.length&&q("div",{className:"mb-3",children:q(b,{groups:E,compact:!0})})]}),q(F,{children:q(L,{items:J})}),q(Z,{children:Q})]})]}),I]}),q("div",{className:"flex items-center gap-2",children:A?.options?.length>1&&q(D,{value:A.value,options:A.options,onChange:A.onChange})})]})})}
1
+ import{jsx as q,jsxs as E}from"react/jsx-runtime";import{VStack as W}from"@contractspec/lib.ui-kit-web/ui/stack";import{cn as X}from"@contractspec/lib.ui-kit-web/ui/utils";import{Menu as Y}from"lucide-react";import*as Z from"react";import{Button as $}from"../atoms/Button";import{CommandSearchTrigger as k}from"../molecules/CommandSearchTrigger";import{LangSwitchDropdown as A}from"../molecules/LangSwitchDropdown";import{MobileNavMenu as B}from"../molecules/MobileNavMenu";import{AdaptivePanel as O}from"../overlays";export function MarketingHeaderMobile({logo:I,nav:J=[],className:K,right:F,commandPaletteGroups:H,langSwitchProps:z}){const[Q,U]=Z.useState(!1);return q("div",{className:X("w-full border-b bg-background/95 backdrop-blur-xs supports-backdrop-filter:bg-background/60 md:hidden",K),children:E("div",{className:"mx-auto flex w-full max-w-7xl items-center justify-between px-3 py-2",children:[E("div",{className:"flex items-center gap-2",children:[q(O,{mode:"drawer",drawerDirection:"left",open:Q,onOpenChange:U,trigger:q($,{variant:"ghost",size:"icon","aria-label":"Open menu",children:q(Y,{className:"h-5 w-5"})}),title:"Menu",className:"w-[320px]",children:E("div",{className:"px-4 pb-4",children:[!!H?.length&&q("div",{className:"mb-3",children:q(k,{groups:H,compact:!0})}),q(W,{children:q(B,{items:J})}),F?q("div",{className:"mt-4",children:F}):null]})}),I]}),q("div",{className:"flex items-center gap-2",children:z?.options?.length>1&&q(A,{value:z.value,options:z.options,onChange:z.onChange})})]})})}
@@ -0,0 +1,26 @@
1
+ import type * as React from 'react';
2
+ export type AdaptivePanelMode = 'sheet' | 'drawer' | 'responsive';
3
+ export type AdaptivePanelBreakpoint = 'sm' | 'md' | 'lg' | number;
4
+ export type AdaptivePanelStaticMode = Exclude<AdaptivePanelMode, 'responsive'>;
5
+ export interface AdaptivePanelProps {
6
+ open: boolean;
7
+ onOpenChange: (open: boolean) => void;
8
+ trigger: React.ReactNode;
9
+ title: React.ReactNode;
10
+ description?: React.ReactNode;
11
+ mode?: AdaptivePanelMode;
12
+ mobileMode?: AdaptivePanelStaticMode;
13
+ desktopMode?: AdaptivePanelStaticMode;
14
+ breakpoint?: AdaptivePanelBreakpoint;
15
+ sheetSide?: 'top' | 'right' | 'bottom' | 'left';
16
+ drawerDirection?: 'top' | 'right' | 'bottom' | 'left';
17
+ className?: string;
18
+ headerClassName?: string;
19
+ titleClassName?: string;
20
+ descriptionClassName?: string;
21
+ sheetClassName?: string;
22
+ drawerClassName?: string;
23
+ children: React.ReactNode;
24
+ }
25
+ export declare function AdaptivePanel({ open, onOpenChange, trigger, title, description, mode, mobileMode, desktopMode, breakpoint, sheetSide, drawerDirection, className, headerClassName, titleClassName, descriptionClassName, sheetClassName, drawerClassName, children, }: AdaptivePanelProps): import("react/jsx-runtime").JSX.Element;
26
+ export declare function toAdaptivePanelBreakpointQuery(breakpoint: AdaptivePanelBreakpoint): string;
@@ -0,0 +1 @@
1
+ import{jsx as F,jsxs as G}from"react/jsx-runtime";import{Drawer as Q,DrawerContent as M,DrawerDescription as O,DrawerHeader as T,DrawerTitle as f,DrawerTrigger as S}from"@contractspec/lib.ui-kit-web/ui/drawer";import{Sheet as u,SheetContent as y,SheetDescription as D,SheetHeader as b,SheetTitle as k,SheetTrigger as x}from"@contractspec/lib.ui-kit-web/ui/sheet";import{useMediaQuery as _}from"@contractspec/lib.ui-kit-web/ui/use-media-query";import{cn as K}from"../../lib/utils";const g={sm:"(min-width: 640px)",md:"(min-width: 768px)",lg:"(min-width: 1024px)"};export function AdaptivePanel({open:z,onOpenChange:L,trigger:V,title:W,description:J,mode:X="responsive",mobileMode:U="drawer",desktopMode:Y="sheet",breakpoint:A="md",sheetSide:B="right",drawerDirection:E="bottom",className:Z,headerClassName:$,titleClassName:q,descriptionClassName:v,sheetClassName:H,drawerClassName:P,children:I}){const R=_(toAdaptivePanelBreakpointQuery(A));if((X==="responsive"?R?Y:U:X)==="drawer")return G(Q,{open:z,onOpenChange:L,direction:E,children:[F(S,{asChild:!0,children:V}),G(M,{className:K("max-h-[85vh]",Z,P),children:[G(T,{className:$,children:[F(f,{className:q,children:W}),J?F(O,{className:v,children:J}):null]}),I]})]});return G(u,{open:z,onOpenChange:L,children:[F(x,{asChild:!0,children:V}),G(y,{side:B,className:K("sm:max-w-md",Z,H),children:[G(b,{className:$,children:[F(k,{className:q,children:W}),J?F(D,{className:v,children:J}):null]}),I]})]})}export function toAdaptivePanelBreakpointQuery(z){return typeof z==="number"?`(min-width: ${z}px)`:g[z]}
@@ -0,0 +1 @@
1
+ export { AdaptivePanel, type AdaptivePanelBreakpoint, type AdaptivePanelMode, type AdaptivePanelProps, type AdaptivePanelStaticMode, toAdaptivePanelBreakpointQuery, } from './AdaptivePanel';
@@ -0,0 +1 @@
1
+ export{AdaptivePanel,toAdaptivePanelBreakpointQuery}from"./AdaptivePanel";
@@ -1,2 +1,2 @@
1
1
  import type { AppShellProps } from './AppShell.types';
2
- export declare function AppShell({ brand, logo, title, homeHref, navigation, commands, breadcrumbs, pageOutline, activeHref, activeOutlineId, userMenu, topbarStart, topbarEnd, children, className, contentClassName, onNavigate: _onNavigate, }: AppShellProps): import("react/jsx-runtime").JSX.Element;
2
+ export declare function AppShell({ brand, logo, title, homeHref, navigation, commands, notifications, breadcrumbs, pageOutline, activeHref, activeOutlineId, userMenu, topbarStart, topbarEnd, children, className, contentClassName, onNavigate: _onNavigate, }: AppShellProps): import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- import{jsx as k,jsxs as F}from"react/jsx-runtime";import{Dialog as R,DialogContent as P,DialogHeader as B,DialogTitle as T}from"@contractspec/lib.ui-kit-web/ui/dialog";import{cn as Q}from"@contractspec/lib.ui-kit-web/ui/utils";import{MenuIcon as w,PanelRightIcon as y}from"lucide-react";import*as D from"react";import{Button as I}from"../atoms/Button";import{NavBrand as g}from"../atoms/NavBrand";import{Breadcrumbs as u}from"../molecules/Breadcrumbs";import{CommandSearchTrigger as _}from"../molecules/CommandSearchTrigger";import{PageOutline as N}from"./PageOutline";import{ShellSidebar as x}from"./ShellSidebar";function d({sections:q,activeHref:G}){return k("nav",{className:"flex flex-col gap-5","aria-label":"Application navigation",children:q.map((A,J)=>F("div",{className:"flex flex-col gap-2",children:[A.title&&k("div",{className:"font-medium text-muted-foreground text-xs uppercase tracking-wide",children:A.title}),k("div",{className:"flex flex-col gap-1",children:A.items.map((z)=>k(C,{item:z,activeHref:G},z.key??z.href??String(z.label)))})]},A.key??J))})}function C({item:q,activeHref:G,depth:A=0}){const J=q.active||Boolean(q.href)&&Boolean(G)&&(q.match==="startsWith"?G?.startsWith(q.href??""):G===q.href),z=F("span",{className:Q("inline-flex min-w-0 items-center gap-2",A>0&&"pl-4"),children:[q.icon,k("span",{className:"truncate",children:q.label}),q.badge?k("span",{className:"ml-auto text-muted-foreground text-xs",children:q.badge}):null]});return F("div",{className:"flex flex-col gap-1",children:[q.href?k("a",{href:q.href,target:q.target,"aria-current":J?"page":void 0,"aria-label":q.ariaLabel,onClick:()=>q.onSelect?.(),className:Q("rounded-xs px-2 py-2 text-sm hover:bg-accent hover:text-accent-foreground",J&&"bg-accent font-medium text-accent-foreground"),children:z}):k("button",{type:"button","aria-label":q.ariaLabel,onClick:()=>q.onSelect?.(),className:Q("rounded-xs px-2 py-2 text-left text-sm hover:bg-accent hover:text-accent-foreground",J&&"bg-accent font-medium text-accent-foreground"),children:z}),q.children?.length?k("div",{className:"flex flex-col gap-1",children:q.children.map((K)=>k(C,{item:K,activeHref:G,depth:A+1},K.key??K.href??String(K.label)))}):null]})}export function AppShell({brand:q,logo:G,title:A,homeHref:J,navigation:z=[],commands:K=[],breadcrumbs:Y=[],pageOutline:U=[],activeHref:Z,activeOutlineId:$,userMenu:V,topbarStart:M,topbarEnd:S,children:b,className:H,contentClassName:p,onNavigate:f}){const[O,E]=D.useState(!1),[v,W]=D.useState(!1),L=q??k(g,{href:J,logo:G,title:A}),X=(h=!1)=>K.length?k(_,{groups:K,placeholder:"Search or run action...",compact:h}):null;return F("div",{className:Q("min-h-svh bg-background",H),children:[k("header",{className:"sticky top-0 z-30 border-b bg-background/95 backdrop-blur-xs supports-backdrop-filter:bg-background/60",children:F("div",{className:"flex h-14 items-center gap-3 px-3 md:px-4",children:[k(I,{variant:"ghost",size:"icon",className:"md:hidden","aria-label":"Open navigation",onPress:()=>E(!0),children:k(w,{className:"h-4 w-4"})}),k("div",{className:"min-w-0 md:hidden",children:L}),k("div",{className:"hidden min-w-0 md:block",children:M}),k("div",{className:"min-w-0 flex-1",children:Y.length?k(u,{items:Y}):null}),k("div",{className:"hidden shrink-0 md:block",children:X()}),U.length?k(I,{variant:"ghost",size:"icon",className:"lg:hidden","aria-label":"Open page outline",onPress:()=>W(!0),children:k(y,{className:"h-4 w-4"})}):null,S,V]})}),F("div",{className:"grid min-h-[calc(100svh-3.5rem)] grid-cols-1 md:grid-cols-[280px_minmax(0,1fr)] lg:grid-cols-[280px_minmax(0,1fr)_240px]",children:[k("aside",{className:"hidden border-r md:block",children:k(x,{sections:z,brand:L,commandTrigger:X(),footer:V,activeHref:Z})}),k("main",{className:Q("min-w-0 px-4 py-5 md:px-6",p),children:b}),U.length?k("aside",{className:"hidden px-4 py-5 lg:block",children:k(N,{items:U,activeId:$})}):null]}),k(R,{open:O,onOpenChange:E,children:F(P,{className:"max-h-[85svh] overflow-auto sm:max-w-sm",children:[k(B,{children:k(T,{children:"Menu"})}),F("div",{className:"flex flex-col gap-4",children:[X(),k(d,{sections:z,activeHref:Z}),V]})]})}),k(R,{open:v,onOpenChange:W,children:F(P,{className:"max-h-[85svh] overflow-auto sm:max-w-sm",children:[k(B,{children:k(T,{children:"On this page"})}),k(N,{items:U,activeId:$,variant:"compact",onNavigate:()=>W(!1)})]})})]})}
1
+ import{jsx as k,jsxs as z}from"react/jsx-runtime";import{Dialog as P,DialogContent as B,DialogHeader as D,DialogTitle as T}from"@contractspec/lib.ui-kit-web/ui/dialog";import{SidebarInset as g,SidebarProvider as h,SidebarTrigger as u}from"@contractspec/lib.ui-kit-web/ui/sidebar";import{cn as U}from"@contractspec/lib.ui-kit-web/ui/utils";import{MenuIcon as _,PanelRightIcon as x}from"lucide-react";import*as C from"react";import{Button as I}from"../atoms/Button";import{NavBrand as f}from"../atoms/NavBrand";import{Breadcrumbs as d}from"../molecules/Breadcrumbs";import{CommandSearchTrigger as j}from"../molecules/CommandSearchTrigger";import{PageOutline as M}from"./PageOutline";import{ShellNotifications as l}from"./ShellNotifications";import{ShellSidebar as o}from"./ShellSidebar";function r({sections:q,activeHref:G}){return k("nav",{className:"flex flex-col gap-5","aria-label":"Application navigation",children:q.map((F,J)=>z("div",{className:"flex flex-col gap-2",children:[F.title&&k("div",{className:"font-medium text-muted-foreground text-xs uppercase tracking-wide",children:F.title}),k("div",{className:"flex flex-col gap-1",children:F.items.map((A)=>k(N,{item:A,activeHref:G},A.key??A.href??String(A.label)))})]},F.key??J))})}function N({item:q,activeHref:G,depth:F=0}){const J=q.active||Boolean(q.href)&&Boolean(G)&&(q.match==="startsWith"?G?.startsWith(q.href??""):G===q.href),A=z("span",{className:U("inline-flex min-w-0 items-center gap-2",F>0&&"pl-4"),children:[q.icon,k("span",{className:"truncate",children:q.label}),q.badge?k("span",{className:"ml-auto text-muted-foreground text-xs",children:q.badge}):null]}),Q=q.disabled||q.policyDecision?.effect==="deny";return z("div",{className:"flex flex-col gap-1",children:[q.href&&!Q?k("a",{href:q.href,target:q.target,"aria-current":J?"page":void 0,"aria-label":q.ariaLabel,onClick:()=>q.onSelect?.(),className:U("rounded-xs px-2 py-2 text-sm hover:bg-accent hover:text-accent-foreground",J&&"bg-accent font-medium text-accent-foreground"),children:A}):k("button",{type:"button","aria-disabled":Q||void 0,disabled:Q,"aria-label":q.ariaLabel,onClick:()=>q.onSelect?.(),className:U("rounded-xs px-2 py-2 text-left text-sm hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50",J&&"bg-accent font-medium text-accent-foreground"),children:A}),q.children?.length?k("div",{className:"flex flex-col gap-1",children:q.children.map((K)=>k(N,{item:K,activeHref:G,depth:F+1},K.key??K.href??String(K.label)))}):null]})}export function AppShell({brand:q,logo:G,title:F,homeHref:J,navigation:A=[],commands:Q=[],notifications:K,breadcrumbs:Z=[],pageOutline:V=[],activeHref:$,activeOutlineId:E,userMenu:W,topbarStart:S,topbarEnd:H,children:b,className:p,contentClassName:O,onNavigate:m}){const[v,L]=C.useState(!1),[w,X]=C.useState(!1),R=q??k(f,{href:J,logo:G,title:F}),Y=(y=!1)=>Q.length?k(j,{groups:Q,placeholder:"Search or run action...",compact:y}):null;return z("div",{className:U("min-h-svh bg-background",p),children:[z(h,{children:[k(o,{sections:A,brand:R,commandTrigger:Y(),footer:W,activeHref:$,withProvider:!1}),z(g,{className:"min-h-svh min-w-0",children:[k("header",{className:"sticky top-0 z-30 border-b bg-background/95 backdrop-blur-xs supports-backdrop-filter:bg-background/60",children:z("div",{className:"flex h-14 min-w-0 items-center gap-3 px-3 md:px-4",children:[k(I,{variant:"ghost",size:"icon",className:"md:hidden",ariaLabelI18n:"Open navigation",onPress:()=>L(!0),children:k(_,{className:"h-4 w-4"})}),k(u,{"aria-label":"Toggle sidebar",className:"hidden md:inline-flex"}),k("div",{className:"min-w-0 md:hidden",children:R}),k("div",{className:"hidden min-w-0 md:block",children:S}),k("div",{className:"min-w-0 flex-1 overflow-hidden",children:Z.length?k(d,{items:Z}):null}),k("div",{className:"hidden shrink-0 md:block",children:Y()}),V.length?k(I,{variant:"ghost",size:"icon",className:"lg:hidden",ariaLabelI18n:"Open page outline",onPress:()=>X(!0),children:k(x,{className:"h-4 w-4"})}):null,z("div",{className:"flex shrink-0 items-center gap-2",children:[K?k(l,{notifications:K}):null,H,W]})]})}),z("div",{className:"grid min-h-0 flex-1 grid-cols-1 lg:grid-cols-[minmax(0,1fr)_240px]",children:[k("div",{className:U("min-w-0 px-4 py-5 md:px-6",O),children:b}),V.length?k("aside",{className:"hidden px-4 py-5 lg:block",children:k(M,{items:V,activeId:E})}):null]})]})]}),k(P,{open:v,onOpenChange:L,children:z(B,{className:"max-h-[85svh] overflow-auto sm:max-w-sm",children:[k(D,{children:k(T,{children:"Menu"})}),z("div",{className:"flex flex-col gap-4",children:[Y(),k(r,{sections:A,activeHref:$}),W]})]})}),k(P,{open:w,onOpenChange:X,children:z(B,{className:"max-h-[85svh] overflow-auto sm:max-w-sm",children:[k(D,{children:k(T,{children:"On this page"})}),k(M,{items:V,activeId:E,variant:"compact",onNavigate:()=>X(!1)})]})})]})}
@@ -1,2 +1,2 @@
1
1
  import type { AppShellProps } from './AppShell.types';
2
- export declare function AppShell({ brand, logo, title, navigation, commands, breadcrumbs, pageOutline, activeHref, activeOutlineId, userMenu, topbarEnd, children, className, homeHref: _homeHref, topbarStart: _topbarStart, contentClassName, onNavigate, }: AppShellProps): import("react/jsx-runtime").JSX.Element;
2
+ export declare function AppShell({ brand, logo, title, navigation, commands, notifications, breadcrumbs, pageOutline, activeHref, activeOutlineId, userMenu, topbarEnd, children, className, homeHref: _homeHref, topbarStart: _topbarStart, contentClassName, onNavigate, }: AppShellProps): import("react/jsx-runtime").JSX.Element;
@@ -1,5 +1,5 @@
1
1
  import type * as React from 'react';
2
- import type { PageOutlineItem, ShellBreadcrumbItem, ShellCommandGroup, ShellNavItem, ShellNavSection } from './types';
2
+ import type { PageOutlineItem, ShellBreadcrumbItem, ShellCommandGroup, ShellNavItem, ShellNavSection, ShellNotificationCenter } from './types';
3
3
  export interface AppShellProps {
4
4
  brand?: React.ReactNode;
5
5
  logo?: React.ReactNode;
@@ -7,6 +7,7 @@ export interface AppShellProps {
7
7
  homeHref?: string;
8
8
  navigation?: ShellNavSection[];
9
9
  commands?: ShellCommandGroup[];
10
+ notifications?: ShellNotificationCenter;
10
11
  breadcrumbs?: ShellBreadcrumbItem[];
11
12
  pageOutline?: PageOutlineItem[];
12
13
  activeHref?: string;
@@ -0,0 +1,5 @@
1
+ import type { ShellNotificationCenter } from './types';
2
+ export interface ShellNotificationsProps {
3
+ notifications: ShellNotificationCenter;
4
+ }
5
+ export declare function ShellNotifications({ notifications }: ShellNotificationsProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ import{jsx as D,jsxs as J,Fragment as F}from"react/jsx-runtime";import{cn as X}from"@contractspec/lib.ui-kit-web/ui/utils";import{BellIcon as B,CheckIcon as q,XIcon as I}from"lucide-react";import*as Y from"react";import{Button as Z}from"../atoms/Button";function E(z){return z.status==="unread"||!z.status&&!z.readAt}function k(z){if(!z)return;return z instanceof Date?z.toLocaleString():z}export function ShellNotifications({notifications:z}){const[G,$]=Y.useState(!1),K=Y.useRef(null),W=Y.useRef(null),M=z.items??[],P=z.unreadCount??M.filter((H)=>E(H)).length,Q=z.label??"Notifications",U=z.emptyLabel??"No notifications",L=z.markAllReadLabel??"Mark all notifications as read",V=Y.useCallback((H)=>{$(H);z.onOpenChange?.(H)},[z]);Y.useEffect(()=>{if(!G)return;const H=(A)=>{const S=A.target;if(!(S instanceof Node))return;if(K.current?.contains(S)||W.current?.contains(S))return;V(!1)},T=(A)=>{if(A.key==="Escape")V(!1)};document.addEventListener("click",H,!0);document.addEventListener("keydown",T);return()=>{document.removeEventListener("click",H,!0);document.removeEventListener("keydown",T)}},[G,V]);return J(F,{children:[D("span",{ref:W,className:"inline-flex",children:J(Z,{variant:"ghost",size:"icon",className:"relative","aria-expanded":G,"aria-haspopup":"dialog",ariaLabelI18n:Q,onPress:()=>V(!G),children:[D(B,{className:"h-4 w-4"}),P>0?D("span",{"aria-label":`${P} unread notifications`,className:"absolute -top-1 -right-1 inline-flex min-h-4 min-w-4 items-center justify-center rounded-full bg-destructive px-1 font-medium text-[10px] text-destructive-foreground leading-none",children:P>99?"99+":P}):null]})}),G?J("div",{ref:K,"aria-label":Q,"aria-modal":"false",className:"fixed top-16 right-4 z-50 max-h-[calc(100svh-5rem)] w-[min(24rem,calc(100vw-2rem))] overflow-auto rounded-md border bg-background p-4 shadow-lg",role:"dialog",children:[J("div",{className:"mb-3 flex items-center justify-between gap-3",children:[D("h2",{className:"font-semibold text-lg",children:Q}),J("div",{className:"flex items-center gap-1",children:[M.length>0&&z.onMarkAllRead?J(Z,{variant:"ghost",size:"sm",ariaLabelI18n:L,onPress:z.onMarkAllRead,children:[D(q,{className:"h-4 w-4"}),D("span",{children:"Mark all read"})]}):null,D(Z,{variant:"ghost",size:"icon",ariaLabelI18n:"Close notifications",onPress:()=>V(!1),children:D(I,{className:"h-4 w-4"})})]})]}),D("div",{className:"flex flex-col gap-2",children:z.loading?D("div",{"aria-live":"polite",className:"py-6 text-center text-muted-foreground text-sm",children:"Loading notifications..."}):M.length?M.map((H)=>D(C,{item:H,notifications:z,onClose:()=>V(!1)},H.id)):D("div",{className:"py-6 text-center text-muted-foreground text-sm",children:U})})]}):null]})}function C({item:z,notifications:G,onClose:$}){const K=E(z),W=k(z.createdAt),M=()=>{G.onSelect?.(z);$()},P=()=>G.onMarkRead?.(z);if(G.renderItem)return D("div",{className:X("rounded-xs border p-3",K&&"bg-muted/50"),children:G.renderItem(z,{unread:K,onSelect:M,onMarkRead:P})});const Q=D(F,{children:J("span",{className:"flex min-w-0 flex-1 flex-col gap-1 text-left",children:[J("span",{className:"flex items-center gap-2",children:[K?D("span",{className:"h-2 w-2 rounded-full bg-primary","aria-hidden":!0}):null,D("span",{className:"font-medium text-sm",children:z.title})]}),z.body?D("span",{className:"text-muted-foreground text-sm",children:z.body}):null,J("span",{className:"flex flex-wrap items-center gap-2 text-muted-foreground text-xs",children:[z.category?D("span",{children:z.category}):null,W?D("time",{children:W}):null]})]})});return J("div",{className:X("flex items-start gap-2 rounded-xs border p-3",K&&"bg-muted/50"),children:[z.actionUrl?D("a",{href:z.actionUrl,className:"min-w-0 flex-1",onClick:M,children:Q}):D("button",{type:"button",className:"min-w-0 flex-1",onClick:M,children:Q}),K&&G.onMarkRead?D(Z,{variant:"ghost",size:"icon",ariaLabelI18n:`Mark ${String(z.title)} as read`,onPress:P,children:D(q,{className:"h-4 w-4"})}):null]})}
@@ -0,0 +1,5 @@
1
+ import type { ShellNotificationCenter } from './types';
2
+ export interface NativeShellNotificationsSectionProps {
3
+ notifications: ShellNotificationCenter;
4
+ }
5
+ export declare function NativeShellNotificationsSection({ notifications, }: NativeShellNotificationsSectionProps): import("react/jsx-runtime").JSX.Element;
@@ -7,5 +7,6 @@ export interface ShellSidebarProps {
7
7
  footer?: React.ReactNode;
8
8
  activeHref?: string;
9
9
  className?: string;
10
+ withProvider?: boolean;
10
11
  }
11
- export declare function ShellSidebar({ sections, brand, commandTrigger, footer, activeHref, className, }: ShellSidebarProps): import("react/jsx-runtime").JSX.Element;
12
+ export declare function ShellSidebar({ sections, brand, commandTrigger, footer, activeHref, className, withProvider, }: ShellSidebarProps): import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- import{jsx as z,jsxs as O}from"react/jsx-runtime";import{Sidebar as A,SidebarContent as F,SidebarFooter as L,SidebarGroup as P,SidebarGroupContent as R,SidebarGroupLabel as B,SidebarHeader as K,SidebarMenu as X,SidebarMenuBadge as N,SidebarMenuButton as C,SidebarMenuItem as G,SidebarProvider as I,SidebarRail as T}from"@contractspec/lib.ui-kit-web/ui/sidebar";import{cn as Y}from"@contractspec/lib.ui-kit-web/ui/utils";function M(q,D){if(q.active)return!0;if(!D||!q.href)return!1;return q.match==="startsWith"?D.startsWith(q.href):D===q.href}function Z(q){return q.key??q.href??String(q.label)}function $({item:q,activeHref:D,depth:J=0}){const Q=M(q,D),V=Boolean(q.children?.length),U=O("span",{className:Y("inline-flex min-w-0 items-center gap-2",J>0&&"pl-4"),children:[q.icon,z("span",{className:"truncate",children:q.label})]});return O(G,{children:[z(C,{asChild:!!q.href,isActive:Q,"aria-label":q.href?void 0:q.ariaLabel,onClick:q.href?void 0:()=>q.onSelect?.(),children:q.href?z("a",{href:q.href,target:q.target,"aria-label":q.ariaLabel,onClick:()=>q.onSelect?.(),children:U}):U}),q.badge!=null&&z(N,{children:q.badge}),V&&z(X,{className:"mt-1",children:q.children?.map((E)=>z($,{item:E,activeHref:D,depth:J+1},Z(E)))})]})}export function ShellSidebar({sections:q,brand:D,commandTrigger:J,footer:Q,activeHref:V,className:U}){return z(I,{children:O(A,{className:U,children:[z(T,{}),O(K,{className:Y("gap-3",!D&&!J&&"hidden"),children:[D,J]}),z(F,{children:q.map((E,k)=>O(P,{children:[E.title&&z(B,{children:E.title}),z(R,{children:z(X,{children:E.items.map((W)=>z($,{item:W,activeHref:V},Z(W)))})})]},E.key??k))}),Q&&z(L,{children:Q})]})})}
1
+ import{jsx as z,jsxs as Q}from"react/jsx-runtime";import{Sidebar as L,SidebarContent as R,SidebarFooter as B,SidebarGroup as K,SidebarGroupContent as N,SidebarGroupLabel as C,SidebarHeader as G,SidebarMenu as Z,SidebarMenuBadge as I,SidebarMenuButton as P,SidebarMenuItem as T,SidebarProvider as M,SidebarRail as p}from"@contractspec/lib.ui-kit-web/ui/sidebar";import{cn as $}from"@contractspec/lib.ui-kit-web/ui/utils";function g(q,D){if(q.active)return!0;if(!D||!q.href)return!1;return q.match==="startsWith"?D.startsWith(q.href):D===q.href}function k(q){return q.key??q.href??String(q.label)}function A({item:q,activeHref:D,depth:J=0}){const U=g(q,D),E=q.disabled||q.policyDecision?.effect==="deny",X=Boolean(q.children?.length),V=Q("span",{className:$("inline-flex min-w-0 items-center gap-2",J>0&&"pl-4"),children:[q.icon,z("span",{className:"truncate",children:q.label})]});return Q(T,{children:[z(P,{asChild:!!q.href&&!E,isActive:U,"aria-disabled":E,"aria-label":q.href&&!E?void 0:q.ariaLabel,disabled:E,onClick:q.href||E?void 0:()=>q.onSelect?.(),children:q.href&&!E?z("a",{href:q.href,target:q.target,"aria-label":q.ariaLabel,onClick:()=>q.onSelect?.(),children:V}):V}),q.badge!=null&&z(I,{children:q.badge}),X&&z(Z,{className:"mt-1",children:q.children?.map((O)=>z(A,{item:O,activeHref:D,depth:J+1},k(O)))})]})}export function ShellSidebar({sections:q,brand:D,commandTrigger:J,footer:U,activeHref:E,className:X,withProvider:V=!0}){const O=Q(L,{className:X,children:[z(p,{}),Q(G,{className:$("gap-3",!D&&!J&&"hidden"),children:[D,J]}),z(R,{children:q.map((W,F)=>Q(K,{children:[W.title&&z(C,{children:W.title}),z(N,{children:z(Z,{children:W.items.map((Y)=>z(A,{item:Y,activeHref:E},k(Y)))})})]},W.key??F))}),U&&z(B,{children:U})]});return V?z(M,{children:O}):O}
@@ -1,5 +1,8 @@
1
1
  export { AppShell } from './AppShell';
2
2
  export type { AppShellProps } from './AppShell.types';
3
3
  export { PageOutline, type PageOutlineProps, usePageOutlineActiveItem, } from './PageOutline';
4
+ export type { PolicyAwareShellCommandItem, PolicyAwareShellNavItem, ShellPolicyAnnotated, ShellPolicyBehavior, ShellPolicyDecisionProvider, } from './policy';
5
+ export { annotateShellCommandsDecisions, annotateShellNavigationDecisions, filterShellNavigationForPolicy, } from './policy';
6
+ export { ShellNotifications, type ShellNotificationsProps, } from './ShellNotifications';
4
7
  export { ShellSidebar, type ShellSidebarProps } from './ShellSidebar';
5
- export type { AppShellConfig, PageOutlineItem, PageOutlineLevel, ShellBreadcrumbItem, ShellCommandGroup, ShellCommandItem, ShellNavItem, ShellNavMatch, ShellNavSection, ShellUserMenu, ShellUserMenuItem, } from './types';
8
+ export type { AppShellConfig, PageOutlineItem, PageOutlineLevel, ShellBreadcrumbItem, ShellCommandGroup, ShellCommandItem, ShellNavItem, ShellNavMatch, ShellNavSection, ShellNotificationCenter, ShellNotificationItem, ShellNotificationRenderContext, ShellNotificationStatus, ShellUserMenu, ShellUserMenuItem, } from './types';
@@ -1 +1 @@
1
- export{AppShell}from"./AppShell";export{PageOutline,usePageOutlineActiveItem}from"./PageOutline";export{ShellSidebar}from"./ShellSidebar";
1
+ export{AppShell}from"./AppShell";export{PageOutline,usePageOutlineActiveItem}from"./PageOutline";export{annotateShellCommandsDecisions,annotateShellNavigationDecisions,filterShellNavigationForPolicy}from"./policy";export{ShellNotifications}from"./ShellNotifications";export{ShellSidebar}from"./ShellSidebar";
@@ -1,4 +1,5 @@
1
1
  export { AppShell } from './AppShell.native';
2
2
  export type { AppShellProps } from './AppShell.types';
3
3
  export { PageOutline, type PageOutlineProps, usePageOutlineActiveItem, } from './PageOutline.native';
4
- export type { AppShellConfig, PageOutlineItem, PageOutlineLevel, ShellBreadcrumbItem, ShellCommandGroup, ShellCommandItem, ShellNavItem, ShellNavMatch, ShellNavSection, ShellUserMenu, ShellUserMenuItem, } from './types';
4
+ export { NativeShellNotificationsSection, type NativeShellNotificationsSectionProps, } from './ShellNotifications.native';
5
+ export type { AppShellConfig, PageOutlineItem, PageOutlineLevel, ShellBreadcrumbItem, ShellCommandGroup, ShellCommandItem, ShellNavItem, ShellNavMatch, ShellNavSection, ShellNotificationCenter, ShellNotificationItem, ShellNotificationRenderContext, ShellNotificationStatus, ShellUserMenu, ShellUserMenuItem, } from './types';
@@ -0,0 +1,15 @@
1
+ import type { PolicyDecision } from '@contractspec/lib.contracts-spec';
2
+ import type { PolicyRequirement } from '@contractspec/lib.contracts-spec/policy';
3
+ import type { ShellCommandGroup, ShellCommandItem, ShellNavItem, ShellNavSection } from './types';
4
+ export type ShellPolicyBehavior = 'hide' | 'disable' | 'show-with-lock';
5
+ export type ShellPolicyDecisionProvider<TItem> = (policy: PolicyRequirement, item: TItem) => PolicyDecision;
6
+ export interface ShellPolicyAnnotated {
7
+ policyDecision?: PolicyDecision;
8
+ disabled?: boolean;
9
+ locked?: boolean;
10
+ }
11
+ export type PolicyAwareShellNavItem = ShellNavItem & ShellPolicyAnnotated;
12
+ export type PolicyAwareShellCommandItem = ShellCommandItem & ShellPolicyAnnotated;
13
+ export declare function filterShellNavigationForPolicy(sections: ShellNavSection[], decisionProvider: ShellPolicyDecisionProvider<ShellNavItem | ShellNavSection>): ShellNavSection[];
14
+ export declare function annotateShellNavigationDecisions(sections: ShellNavSection[], decisionProvider: ShellPolicyDecisionProvider<ShellNavItem | ShellNavSection>): ShellNavSection[];
15
+ export declare function annotateShellCommandsDecisions(groups: ShellCommandGroup[], decisionProvider: ShellPolicyDecisionProvider<ShellCommandItem>): ShellCommandGroup[];
@@ -0,0 +1 @@
1
+ export function filterShellNavigationForPolicy(q,y){return annotateShellNavigationDecisions(q,y)}export function annotateShellNavigationDecisions(q,y){return q.flatMap((f)=>{const w=f.policy?y(f.policy,f):void 0,j=f.policyBehavior??"hide";if(w?.effect==="deny"&&j==="hide")return[];const k=f.items.flatMap((z)=>F(z,y));if(!k.length&&j==="hide")return[];if(!w&&k.length===f.items.length&&k.every((z,E)=>z===f.items[E]))return[f];return[{...f,items:k,policyDecision:w,disabled:w?.effect==="deny"&&j==="disable",locked:w?.effect==="deny"&&j==="show-with-lock"}]})}export function annotateShellCommandsDecisions(q,y){return q.flatMap((f)=>{const w=f.items.flatMap((j)=>{if(!j.policy)return[j];const k=y(j.policy,j);if(k.effect==="allow")return[{...j,policyDecision:k}];const A=j.policyBehavior??"disable";if(A==="hide")return[];return[{...j,policyDecision:k,disabled:A==="disable",locked:A==="show-with-lock"}]});return w.length?[{...f,items:w}]:[]})}function F(q,y){const f=q.policy?y(q.policy,q):void 0,w=q.policyBehavior??"hide";if(f?.effect==="deny"&&w==="hide")return[];const j=q.children,k=j?.flatMap((z)=>F(z,y));if(j?.length&&!k?.length&&!q.href&&w==="hide")return[];const A=!j&&!k||!!k&&k.length===j?.length&&k.every((z,E)=>z===j?.[E]);if(!f&&A)return[q];return[{...q,children:k,policyDecision:f,disabled:f?.effect==="deny"&&w==="disable",locked:f?.effect==="deny"&&w==="show-with-lock"}]}
@@ -1,6 +1,13 @@
1
+ import type { PolicyDecision } from '@contractspec/lib.contracts-spec';
2
+ import type { PolicyRequirement } from '@contractspec/lib.contracts-spec/policy';
1
3
  import type * as React from 'react';
2
4
  export type ShellNavMatch = 'exact' | 'startsWith';
3
5
  export interface ShellNavItem {
6
+ policy?: PolicyRequirement;
7
+ policyBehavior?: 'hide' | 'disable' | 'show-with-lock';
8
+ policyDecision?: PolicyDecision;
9
+ disabled?: boolean;
10
+ locked?: boolean;
4
11
  key?: string;
5
12
  label: React.ReactNode;
6
13
  href?: string;
@@ -17,11 +24,21 @@ export interface ShellNavItem {
17
24
  commandId?: string;
18
25
  }
19
26
  export interface ShellNavSection {
27
+ policy?: PolicyRequirement;
28
+ policyBehavior?: 'hide' | 'disable' | 'show-with-lock';
29
+ policyDecision?: PolicyDecision;
30
+ disabled?: boolean;
31
+ locked?: boolean;
20
32
  key?: string;
21
33
  title?: React.ReactNode;
22
34
  items: ShellNavItem[];
23
35
  }
24
36
  export interface ShellCommandItem {
37
+ policy?: PolicyRequirement;
38
+ policyBehavior?: 'hide' | 'disable' | 'show-with-lock';
39
+ policyDecision?: PolicyDecision;
40
+ disabled?: boolean;
41
+ locked?: boolean;
25
42
  id: string;
26
43
  label: string;
27
44
  shortcut?: string;
@@ -35,6 +52,38 @@ export interface ShellBreadcrumbItem {
35
52
  href?: string;
36
53
  label: React.ReactNode;
37
54
  }
55
+ export type ShellNotificationStatus = 'unread' | 'read' | 'archived' | string;
56
+ export interface ShellNotificationItem {
57
+ id: string;
58
+ title: React.ReactNode;
59
+ body?: React.ReactNode;
60
+ type?: string;
61
+ status?: ShellNotificationStatus;
62
+ readAt?: string | Date | null;
63
+ createdAt?: string | Date;
64
+ actionUrl?: string;
65
+ priority?: 'low' | 'normal' | 'high' | 'urgent' | string;
66
+ category?: string;
67
+ metadata?: Record<string, unknown>;
68
+ }
69
+ export interface ShellNotificationRenderContext {
70
+ unread: boolean;
71
+ onSelect: () => void;
72
+ onMarkRead: () => void;
73
+ }
74
+ export interface ShellNotificationCenter {
75
+ items?: ShellNotificationItem[];
76
+ unreadCount?: number;
77
+ loading?: boolean;
78
+ emptyLabel?: React.ReactNode;
79
+ label?: string;
80
+ markAllReadLabel?: string;
81
+ onOpenChange?: (open: boolean) => void;
82
+ onSelect?: (item: ShellNotificationItem) => void;
83
+ onMarkRead?: (item: ShellNotificationItem) => void;
84
+ onMarkAllRead?: () => void;
85
+ renderItem?: (item: ShellNotificationItem, context: ShellNotificationRenderContext) => React.ReactNode;
86
+ }
38
87
  export interface ShellUserMenuItem {
39
88
  label: React.ReactNode;
40
89
  href?: string;
@@ -60,6 +109,7 @@ export interface AppShellConfig {
60
109
  brand?: React.ReactNode;
61
110
  navigation?: ShellNavSection[];
62
111
  commands?: ShellCommandGroup[];
112
+ notifications?: ShellNotificationCenter;
63
113
  breadcrumbs?: ShellBreadcrumbItem[];
64
114
  userMenu?: React.ReactNode;
65
115
  pageOutline?: PageOutlineItem[];
@@ -1,6 +1,7 @@
1
1
  import type { TranslationRegistry } from '@contractspec/lib.contracts-spec/translations';
2
+ import type { RuntimeValues, TranslationRuntime } from '@contractspec/lib.translation-runtime';
2
3
  import * as React from 'react';
3
- export type DesignSystemTranslationResolver = (key: string) => string | undefined;
4
+ export type DesignSystemTranslationResolver = (key: string, values?: RuntimeValues) => string | undefined;
4
5
  export declare function DesignSystemTranslationProvider({ children, resolver, }: {
5
6
  children: React.ReactNode;
6
7
  resolver?: DesignSystemTranslationResolver;
@@ -14,3 +15,7 @@ export declare function createTranslationResolver({ registry, locale, fallbackLo
14
15
  fallbackLocale?: string;
15
16
  specKeys?: string[];
16
17
  }): DesignSystemTranslationResolver;
18
+ export declare function createRuntimeTranslationResolver({ runtime, onMissing, }: {
19
+ runtime: TranslationRuntime;
20
+ onMissing?: 'key' | 'empty' | 'throw';
21
+ }): DesignSystemTranslationResolver;
@@ -1 +1 @@
1
- import{jsx as g}from"react/jsx-runtime";import*as a from"react";const l=a.createContext(void 0);export function DesignSystemTranslationProvider({children:e,resolver:n}){return g(l.Provider,{value:n,children:e})}export function useDesignSystemTranslation(){return a.useContext(l)}export function resolveTranslationString(e,n){if(!e)return e;return n?.(e)??e}export function resolveTranslationNode(e,n){return typeof e==="string"?resolveTranslationString(e,n):e}export function createTranslationResolver({registry:e,locale:n,fallbackLocale:o,specKeys:c=[]}){return(i)=>{const r=i.match(/^([^:]+)::(.+)$/);if(r?.[1]&&r[2]){const[,s,t]=r;return e.getWithFallback(s,t,n,o)?.message.value}for(const s of c){const t=e.getWithFallback(s,i,n,o);if(t)return t.message.value}return}}
1
+ import{jsx as u}from"react/jsx-runtime";import*as l from"react";const c=l.createContext(void 0);export function DesignSystemTranslationProvider({children:e,resolver:n}){return u(c.Provider,{value:n,children:e})}export function useDesignSystemTranslation(){return l.useContext(c)}export function resolveTranslationString(e,n){if(!e)return e;return n?.(e)??e}export function resolveTranslationNode(e,n){return typeof e==="string"?resolveTranslationString(e,n):e}export function createTranslationResolver({registry:e,locale:n,fallbackLocale:s,specKeys:a=[]}){return(o)=>{const i=o.match(/^([^:]+)::(.+)$/);if(i?.[1]&&i[2]){const[,r,t]=i;return e.getWithFallback(r,t,n,s)?.message.value}for(const r of a){const t=e.getWithFallback(r,o,n,s);if(t)return t.message.value}return}}export function createRuntimeTranslationResolver({runtime:e,onMissing:n}){return(s,a)=>{const o=s.match(/^([^:]+)::(.+)$/),i=o?.[1],r=o?.[2]??s,t=e.tUnknown(r,a,{onMissing:n,specKey:i});return t===r&&n!=="key"?void 0:t}}
package/dist/index.d.ts CHANGED
@@ -81,7 +81,7 @@ export { SkeletonList } from './components/molecules/SkeletonList';
81
81
  export { StatCard, StatCardGroup } from './components/molecules/StatCard';
82
82
  export { StatusChip } from './components/molecules/StatusChip';
83
83
  export { Tabs, TabsContent, type TabsContentProps, TabsList, type TabsListProps, type TabsProps, TabsTrigger, type TabsTriggerProps, } from './components/molecules/Tabs';
84
- export { createCopyReferenceAction, createDefaultObjectReferenceActions, createMapsProviderHref, createMapsReferenceActions, createOpenReferenceAction, createPhoneReferenceAction, getObjectReferenceDisplayValue, type ObjectReferenceActionDescriptor, type ObjectReferenceActionEvent, type ObjectReferenceActionHandler, type ObjectReferenceCopyHandler, type ObjectReferenceDescriptor, ObjectReferenceHandler, type ObjectReferenceHandlerProps, type ObjectReferenceInteractivityVisibility, type ObjectReferenceKind, type ObjectReferenceMapsProvider, type ObjectReferenceMetadata, type ObjectReferenceOpenHrefHandler, } from './components/object-reference';
84
+ export { createCopyReferenceAction, createDefaultObjectReferenceActions, createEmailReferenceAction, createMapsProviderHref, createMapsReferenceActions, createOpenReferenceAction, createPhoneReferenceAction, getObjectReferenceDisplayValue, normalizeSafeObjectReferenceHref, type ObjectReferenceActionDescriptor, type ObjectReferenceActionEvent, type ObjectReferenceActionHandler, type ObjectReferenceCopyHandler, type ObjectReferenceDescriptor, ObjectReferenceHandler, type ObjectReferenceHandlerProps, type ObjectReferenceInteractivityVisibility, type ObjectReferenceKind, type ObjectReferenceMapsProvider, type ObjectReferenceMetadata, type ObjectReferenceOpenHrefHandler, type ObjectReferenceOpenTarget, type ObjectReferencePanelBreakpoint, type ObjectReferencePanelMode, type ObjectReferencePropertyRenderContext, type ObjectReferenceSectionDescriptor, type ObjectReferenceSectionRenderContext, SAFE_OBJECT_REFERENCE_PROTOCOLS, } from './components/object-reference';
85
85
  export { AcademyLayout } from './components/organisms/AcademyLayout';
86
86
  export { AppHeader } from './components/organisms/AppHeader';
87
87
  export { AppLayout } from './components/organisms/AppLayout';
@@ -108,6 +108,7 @@ export { PageHeaderResponsive } from './components/organisms/PageHeaderResponsiv
108
108
  export { PricingCarousel } from './components/organisms/PricingCarousel';
109
109
  export { PricingSection } from './components/organisms/PricingSection';
110
110
  export { TestimonialCarousel } from './components/organisms/TestimonialCarousel';
111
+ export * from './components/overlays';
111
112
  export { PackageManagerProvider, type PackageManagerProviderProps, usePackageManager, } from './components/providers/PackageManagerProvider';
112
113
  export type { AppShellConfig, PageOutlineItem, PageOutlineLevel, ShellBreadcrumbItem, ShellCommandGroup, ShellCommandItem, ShellNavItem, ShellNavMatch, ShellNavSection, ShellUserMenu, ShellUserMenuItem, } from './components/shell';
113
114
  export { AppShell, type AppShellProps, PageOutline, type PageOutlineProps, ShellSidebar, type ShellSidebarProps, usePageOutlineActiveItem, } from './components/shell';
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- export{AgentMonitor}from"./components/agent/AgentMonitor";export{ApprovalQueue}from"./components/agent/ApprovalQueue";export{DeleteButton,EditButton,ToggleButton,ToggleLeftButton,ToggleRightButton,ViewButton}from"./components/atoms/ActionButtons";export{Button}from"./components/atoms/Button";export{ButtonLink}from"./components/atoms/ButtonLink";export{Cta}from"./components/atoms/Cta";export{DateChip,DurationChip,PlaceChip,TimeChip}from"./components/atoms/DataChips";export{EmptyState}from"./components/atoms/EmptyState";export{ErrorState}from"./components/atoms/ErrorState";export{Input}from"./components/atoms/Input";export{InputPassword}from"./components/atoms/InputPassword";export{Link}from"./components/atoms/Link";export{LoaderCircular}from"./components/atoms/LoaderCircular";export{NavBrand}from"./components/atoms/NavBrand";export{RankBadge}from"./components/atoms/RankBadge";export{ScoreBar}from"./components/atoms/ScoreBar";export{Stepper}from"./components/atoms/Stepper";export{Textarea}from"./components/atoms/Textarea";export{DataTable}from"./components/data-table/DataTable";export{DataTableToolbar}from"./components/data-table/DataTableToolbar";export{DataViewDetail}from"./components/data-view/DataViewDetail";export{DataViewGrid}from"./components/data-view/DataViewGrid";export{DataViewList}from"./components/data-view/DataViewList";export{DataViewRenderer}from"./components/data-view/DataViewRenderer";export{DataViewTable}from"./components/data-view/DataViewTable";export*from"./components/forms";export*from"./components/layout";export{DefinitionList}from"./components/legal/atoms/DefinitionList";export{KeyValueList}from"./components/legal/atoms/KeyValueList";export{LegalCallout}from"./components/legal/atoms/LegalCallout";export{LegalHeading}from"./components/legal/atoms/LegalHeading";export{LegalList}from"./components/legal/atoms/LegalList";export{LegalSection}from"./components/legal/atoms/LegalSection";export{LegalText}from"./components/legal/atoms/LegalText";export{ConsentItem,ConsentList}from"./components/legal/molecules/Consent";export{ContactFields}from"./components/legal/molecules/ContactFields";export{LegalMeta}from"./components/legal/molecules/LegalMeta";export{LegalTOC}from"./components/legal/molecules/LegalTOC";export*from"./components/legal/organisms/ContactForm";export*from"./components/legal/organisms/GDPRDataRequest";export*from"./components/legal/organisms/GDPRRights";export*from"./components/legal/organisms/LegalPageLayout";export{ContactTemplate}from"./components/legal/templates/ContactTemplate";export{CookiesTemplate}from"./components/legal/templates/CookiesTemplate";export{PrivacyTemplate}from"./components/legal/templates/PrivacyTemplate";export{SalesTermsTemplate}from"./components/legal/templates/SalesTermsTemplate";export{TermsTemplate}from"./components/legal/templates/TermsTemplate";export{List,ListItem}from"./components/list";export{MarketingCard,MarketingCardContent,MarketingCardDescription,MarketingCardHeader,MarketingCardTitle}from"./components/marketing/MarketingCard";export{MarketingCardsSection}from"./components/marketing/MarketingCardsSection";export{MarketingComparisonSection}from"./components/marketing/MarketingComparisonSection";export{MarketingIconCard}from"./components/marketing/MarketingIconCard";export{MarketingSection}from"./components/marketing/MarketingSection";export{MarketingStepCard}from"./components/marketing/MarketingStepCard";export{AiLinkButton}from"./components/molecules/AiLinkButton";export{Breadcrumbs}from"./components/molecules/Breadcrumbs";export{CodeBlock}from"./components/molecules/CodeBlock";export{CommandPalette}from"./components/molecules/CommandPalette";export{CommandSearchTrigger}from"./components/molecules/CommandSearchTrigger";export{CommandTabs}from"./components/molecules/CommandTabs";export{CopyButton}from"./components/molecules/CopyButton";export{DimensionScoresCard}from"./components/molecules/DimensionScoresCard";export{EntityCard}from"./components/molecules/EntityCard";export{FiltersToolbar}from"./components/molecules/FiltersToolbar";export{HoverPreview}from"./components/molecules/HoverPreview";export{HoverPreviewDoc}from"./components/molecules/hover-previews/Doc";export{HoverPreviewMedia}from"./components/molecules/hover-previews/Media";export{HoverPreviewSimple}from"./components/molecules/hover-previews/Simple";export{HoverPreviewStats}from"./components/molecules/hover-previews/Stats";export{HoverPreviewUser}from"./components/molecules/hover-previews/User";export{InstallCommand}from"./components/molecules/InstallCommand";export{LangSwitch}from"./components/molecules/LangSwitch";export{LoaderBlock}from"./components/molecules/LoaderBlock";export{MarkdownRenderer}from"./components/molecules/MarkdownRenderer";export{NavMain}from"./components/molecules/NavMain";export{NavUser}from"./components/molecules/NavUser";export{OverviewCard}from"./components/molecules/OverviewCard";export{SkeletonBlock}from"./components/molecules/SkeletonBlock";export{SkeletonCircle}from"./components/molecules/SkeletonCircle";export{SkeletonList}from"./components/molecules/SkeletonList";export{StatCard,StatCardGroup}from"./components/molecules/StatCard";export{StatusChip}from"./components/molecules/StatusChip";export{Tabs,TabsContent,TabsList,TabsTrigger}from"./components/molecules/Tabs";export{createCopyReferenceAction,createDefaultObjectReferenceActions,createMapsProviderHref,createMapsReferenceActions,createOpenReferenceAction,createPhoneReferenceAction,getObjectReferenceDisplayValue,ObjectReferenceHandler}from"./components/object-reference";export{AcademyLayout}from"./components/organisms/AcademyLayout";export{AppHeader}from"./components/organisms/AppHeader";export{AppLayout}from"./components/organisms/AppLayout";export{AppSidebar}from"./components/organisms/AppSidebar";export{EmptyDataList}from"./components/organisms/EmptyDataList";export{EmptySearchResult}from"./components/organisms/EmptySearchResult";export{FAQSection}from"./components/organisms/FAQSection";export{FeatureCarousel}from"./components/organisms/FeatureCarousel";export{FeaturesSection}from"./components/organisms/FeaturesSection";export{Footer}from"./components/organisms/Footer";export{DesktopHeader,Header,MobileHeader}from"./components/organisms/Header";export{HeroResponsive}from"./components/organisms/HeroResponsive";export{HeroSection}from"./components/organisms/HeroSection";export{ListCardPage}from"./components/organisms/ListCardPage";export{ListGridPage}from"./components/organisms/ListGridPage";export{ListPageResponsive}from"./components/organisms/ListPageResponsive";export{ListTablePage}from"./components/organisms/ListTablePage";export{MarketingHeader}from"./components/organisms/MarketingHeader";export{MarketingHeaderDesktop}from"./components/organisms/MarketingHeaderDesktop";export{MarketingHeaderMobile}from"./components/organisms/MarketingHeaderMobile";export{MarketingLayout}from"./components/organisms/MarketingLayout";export{ModelComparisonView}from"./components/organisms/ModelComparisonView";export{PageHeaderResponsive}from"./components/organisms/PageHeaderResponsive";export{PricingCarousel}from"./components/organisms/PricingCarousel";export{PricingSection}from"./components/organisms/PricingSection";export{TestimonialCarousel}from"./components/organisms/TestimonialCarousel";export{PackageManagerProvider,usePackageManager}from"./components/providers/PackageManagerProvider";export{AppShell,PageOutline,ShellSidebar,usePageOutlineActiveItem}from"./components/shell";export{ListPageTemplate}from"./components/templates/lists/ListPageTemplate";export{BlockQuote,Code,H1,H2,H3,H4,Large,Lead,Muted,P,Small,Text}from"./components/typography";export{ComparisonView}from"./components/visualization/ComparisonView";export{TimelineView}from"./components/visualization/TimelineView";export{VisualizationCard}from"./components/visualization/VisualizationCard";export{VisualizationGrid}from"./components/visualization/VisualizationGrid";export{VisualizationRenderer}from"./components/visualization/VisualizationRenderer";export*from"./design-system.feature";export{useListUrlState}from"./hooks/useListUrlState";export*from"./i18n/translation";export{useColorScheme}from"./platform/useColorScheme";export{useReducedMotion}from"./platform/useReducedMotion";export{useResponsive}from"./platform/useResponsive";export*from"./platform/withPlatformUI";export*from"./renderers";export*from"./theme";export*from"./types/navigation";
1
+ export{AgentMonitor}from"./components/agent/AgentMonitor";export{ApprovalQueue}from"./components/agent/ApprovalQueue";export{DeleteButton,EditButton,ToggleButton,ToggleLeftButton,ToggleRightButton,ViewButton}from"./components/atoms/ActionButtons";export{Button}from"./components/atoms/Button";export{ButtonLink}from"./components/atoms/ButtonLink";export{Cta}from"./components/atoms/Cta";export{DateChip,DurationChip,PlaceChip,TimeChip}from"./components/atoms/DataChips";export{EmptyState}from"./components/atoms/EmptyState";export{ErrorState}from"./components/atoms/ErrorState";export{Input}from"./components/atoms/Input";export{InputPassword}from"./components/atoms/InputPassword";export{Link}from"./components/atoms/Link";export{LoaderCircular}from"./components/atoms/LoaderCircular";export{NavBrand}from"./components/atoms/NavBrand";export{RankBadge}from"./components/atoms/RankBadge";export{ScoreBar}from"./components/atoms/ScoreBar";export{Stepper}from"./components/atoms/Stepper";export{Textarea}from"./components/atoms/Textarea";export{DataTable}from"./components/data-table/DataTable";export{DataTableToolbar}from"./components/data-table/DataTableToolbar";export{DataViewDetail}from"./components/data-view/DataViewDetail";export{DataViewGrid}from"./components/data-view/DataViewGrid";export{DataViewList}from"./components/data-view/DataViewList";export{DataViewRenderer}from"./components/data-view/DataViewRenderer";export{DataViewTable}from"./components/data-view/DataViewTable";export*from"./components/forms";export*from"./components/layout";export{DefinitionList}from"./components/legal/atoms/DefinitionList";export{KeyValueList}from"./components/legal/atoms/KeyValueList";export{LegalCallout}from"./components/legal/atoms/LegalCallout";export{LegalHeading}from"./components/legal/atoms/LegalHeading";export{LegalList}from"./components/legal/atoms/LegalList";export{LegalSection}from"./components/legal/atoms/LegalSection";export{LegalText}from"./components/legal/atoms/LegalText";export{ConsentItem,ConsentList}from"./components/legal/molecules/Consent";export{ContactFields}from"./components/legal/molecules/ContactFields";export{LegalMeta}from"./components/legal/molecules/LegalMeta";export{LegalTOC}from"./components/legal/molecules/LegalTOC";export*from"./components/legal/organisms/ContactForm";export*from"./components/legal/organisms/GDPRDataRequest";export*from"./components/legal/organisms/GDPRRights";export*from"./components/legal/organisms/LegalPageLayout";export{ContactTemplate}from"./components/legal/templates/ContactTemplate";export{CookiesTemplate}from"./components/legal/templates/CookiesTemplate";export{PrivacyTemplate}from"./components/legal/templates/PrivacyTemplate";export{SalesTermsTemplate}from"./components/legal/templates/SalesTermsTemplate";export{TermsTemplate}from"./components/legal/templates/TermsTemplate";export{List,ListItem}from"./components/list";export{MarketingCard,MarketingCardContent,MarketingCardDescription,MarketingCardHeader,MarketingCardTitle}from"./components/marketing/MarketingCard";export{MarketingCardsSection}from"./components/marketing/MarketingCardsSection";export{MarketingComparisonSection}from"./components/marketing/MarketingComparisonSection";export{MarketingIconCard}from"./components/marketing/MarketingIconCard";export{MarketingSection}from"./components/marketing/MarketingSection";export{MarketingStepCard}from"./components/marketing/MarketingStepCard";export{AiLinkButton}from"./components/molecules/AiLinkButton";export{Breadcrumbs}from"./components/molecules/Breadcrumbs";export{CodeBlock}from"./components/molecules/CodeBlock";export{CommandPalette}from"./components/molecules/CommandPalette";export{CommandSearchTrigger}from"./components/molecules/CommandSearchTrigger";export{CommandTabs}from"./components/molecules/CommandTabs";export{CopyButton}from"./components/molecules/CopyButton";export{DimensionScoresCard}from"./components/molecules/DimensionScoresCard";export{EntityCard}from"./components/molecules/EntityCard";export{FiltersToolbar}from"./components/molecules/FiltersToolbar";export{HoverPreview}from"./components/molecules/HoverPreview";export{HoverPreviewDoc}from"./components/molecules/hover-previews/Doc";export{HoverPreviewMedia}from"./components/molecules/hover-previews/Media";export{HoverPreviewSimple}from"./components/molecules/hover-previews/Simple";export{HoverPreviewStats}from"./components/molecules/hover-previews/Stats";export{HoverPreviewUser}from"./components/molecules/hover-previews/User";export{InstallCommand}from"./components/molecules/InstallCommand";export{LangSwitch}from"./components/molecules/LangSwitch";export{LoaderBlock}from"./components/molecules/LoaderBlock";export{MarkdownRenderer}from"./components/molecules/MarkdownRenderer";export{NavMain}from"./components/molecules/NavMain";export{NavUser}from"./components/molecules/NavUser";export{OverviewCard}from"./components/molecules/OverviewCard";export{SkeletonBlock}from"./components/molecules/SkeletonBlock";export{SkeletonCircle}from"./components/molecules/SkeletonCircle";export{SkeletonList}from"./components/molecules/SkeletonList";export{StatCard,StatCardGroup}from"./components/molecules/StatCard";export{StatusChip}from"./components/molecules/StatusChip";export{Tabs,TabsContent,TabsList,TabsTrigger}from"./components/molecules/Tabs";export{createCopyReferenceAction,createDefaultObjectReferenceActions,createEmailReferenceAction,createMapsProviderHref,createMapsReferenceActions,createOpenReferenceAction,createPhoneReferenceAction,getObjectReferenceDisplayValue,normalizeSafeObjectReferenceHref,ObjectReferenceHandler,SAFE_OBJECT_REFERENCE_PROTOCOLS}from"./components/object-reference";export{AcademyLayout}from"./components/organisms/AcademyLayout";export{AppHeader}from"./components/organisms/AppHeader";export{AppLayout}from"./components/organisms/AppLayout";export{AppSidebar}from"./components/organisms/AppSidebar";export{EmptyDataList}from"./components/organisms/EmptyDataList";export{EmptySearchResult}from"./components/organisms/EmptySearchResult";export{FAQSection}from"./components/organisms/FAQSection";export{FeatureCarousel}from"./components/organisms/FeatureCarousel";export{FeaturesSection}from"./components/organisms/FeaturesSection";export{Footer}from"./components/organisms/Footer";export{DesktopHeader,Header,MobileHeader}from"./components/organisms/Header";export{HeroResponsive}from"./components/organisms/HeroResponsive";export{HeroSection}from"./components/organisms/HeroSection";export{ListCardPage}from"./components/organisms/ListCardPage";export{ListGridPage}from"./components/organisms/ListGridPage";export{ListPageResponsive}from"./components/organisms/ListPageResponsive";export{ListTablePage}from"./components/organisms/ListTablePage";export{MarketingHeader}from"./components/organisms/MarketingHeader";export{MarketingHeaderDesktop}from"./components/organisms/MarketingHeaderDesktop";export{MarketingHeaderMobile}from"./components/organisms/MarketingHeaderMobile";export{MarketingLayout}from"./components/organisms/MarketingLayout";export{ModelComparisonView}from"./components/organisms/ModelComparisonView";export{PageHeaderResponsive}from"./components/organisms/PageHeaderResponsive";export{PricingCarousel}from"./components/organisms/PricingCarousel";export{PricingSection}from"./components/organisms/PricingSection";export{TestimonialCarousel}from"./components/organisms/TestimonialCarousel";export*from"./components/overlays";export{PackageManagerProvider,usePackageManager}from"./components/providers/PackageManagerProvider";export{AppShell,PageOutline,ShellSidebar,usePageOutlineActiveItem}from"./components/shell";export{ListPageTemplate}from"./components/templates/lists/ListPageTemplate";export{BlockQuote,Code,H1,H2,H3,H4,Large,Lead,Muted,P,Small,Text}from"./components/typography";export{ComparisonView}from"./components/visualization/ComparisonView";export{TimelineView}from"./components/visualization/TimelineView";export{VisualizationCard}from"./components/visualization/VisualizationCard";export{VisualizationGrid}from"./components/visualization/VisualizationGrid";export{VisualizationRenderer}from"./components/visualization/VisualizationRenderer";export*from"./design-system.feature";export{useListUrlState}from"./hooks/useListUrlState";export*from"./i18n/translation";export{useColorScheme}from"./platform/useColorScheme";export{useReducedMotion}from"./platform/useReducedMotion";export{useResponsive}from"./platform/useResponsive";export*from"./platform/withPlatformUI";export*from"./renderers";export*from"./theme";export*from"./types/navigation";
@@ -1 +1 @@
1
- import{jsx as W,jsxs as T,Fragment as hB}from"react/jsx-runtime";import{resolveDataViewFilters as GB}from"@contractspec/lib.contracts-spec/data-views";import{Pagination as qB}from"@contractspec/lib.ui-kit-web/ui/atoms/Pagination";import{VStack as KB}from"@contractspec/lib.ui-kit-web/ui/stack";import{Text as LB}from"@contractspec/lib.ui-kit-web/ui/text";import{Grid3X3 as IB,List as PB,Table2 as EB}from"lucide-react";import*as I from"react";import{resolveTranslationString as n,useDesignSystemTranslation as NB}from"../../i18n/translation";import{Button as V}from"../atoms/Button";import{Input as b}from"../atoms/Input";import{FiltersToolbar as RB}from"../molecules/FiltersToolbar";import{getDataViewCollectionConfig as TB,getDataViewCollectionViewModesConfig as AB,isDataViewCollectionKind as i,resolveAllowedCollectionModes as _B,resolveCollectionDensity as jB,resolveCollectionView as MB}from"./collection";import{DataViewDetail as VB}from"./DataViewDetail";import{DataViewGrid as kB}from"./DataViewGrid";import{DataViewList as SB}from"./DataViewList";import{DataViewTable as DB}from"./DataViewTable";export function DataViewRenderer({spec:B,items:H=[],item:O=null,className:U,renderActions:J,onSelect:Y,onRowClick:Z,toolbar:A,loading:q,headerActions:X,emptyState:E,footer:w,viewMode:F,defaultViewMode:C,onViewModeChange:HB,density:h,defaultDensity:g,onDensityChange:JB,search:OB,onSearchChange:y,filters:z,onFilterChange:N,pagination:K,onPageChange:p}){const k=NB(),S=I.useMemo(()=>_B(B.view),[B.view]),[QB,UB]=I.useState(C),u=F??QB??C,_=I.useMemo(()=>MB(B,u),[u,B]),[WB,YB]=I.useState(g),P=jB(B,{density:h??WB,defaultDensity:g}),ZB=TB(B.view),$B=AB(B.view),$=ZB?.toolbar,j=$?.enabled!==!1,v=$?.filters!==!1,M=$?.actions??"end",d=M==="start"||M==="both"?X:void 0,f=M==="end"||M==="both"?X:void 0,c=typeof $?.search==="object"?$.search:void 0,r=Boolean(j&&$?.search!==!1&&y),G=I.useMemo(()=>GB({filters:B.view.filters,scope:B.view.filterScope,user:bB(z)}),[z,B.view.filterScope,B.view.filters]),o=I.useMemo(()=>{if(B.view.filterScope){const Q=Object.entries(G.user).map(([L,R])=>({key:L,label:`${a(B,L)}: ${l(R)}`,onRemove:()=>{const{[L]:yB,...zB}=G.user;N?.(zB)}})),D=G.lockedChips==="hidden"?[]:Object.entries(G.locked).map(([L,R])=>({key:`locked-${L}`,label:`${a(B,L)}: ${l(R)}`,disabled:!0}));return[...Q,...D]}return z?Object.entries(z).map(([Q,D])=>({key:Q,label:`${Q}: ${String(D)}`,onRemove:()=>{const{[Q]:L,...R}=z;N?.(R)}})):[]},[z,N,G,B]),XB=B.view.filterScope?Object.keys(G.user).length>0:Boolean(z&&Object.keys(z).length>0),s=I.useMemo(()=>{const Q=i(B.view.kind)?_.spec:B;switch(Q.view.kind){case"list":return W(SB,{spec:Q,items:H,className:U,renderActions:J,onSelect:Y,emptyState:E,density:P});case"table":return W(DB,{spec:Q,items:H,className:U,onRowClick:Z,toolbar:A,loading:q,emptyState:E,headerActions:j?void 0:X,footer:w,density:P});case"detail":return W(VB,{spec:B,item:O,className:U,emptyState:E,headerActions:X});case"grid":return W(kB,{spec:Q,items:H,className:U,renderActions:J,onSelect:Y,emptyState:E,density:P});default:return W(LB,{className:U,children:n("Unsupported data view kind",k)})}},[B,_.spec,H,O,U,J,Y,Z,A,q,X,E,w,P,j,k]);if(!(B.view.kind==="list"||B.view.kind==="table"||B.view.kind==="grid"))return W(hB,{children:s});return T(KB,{gap:"lg",children:[j&&(v&&B.view.filters?.length||r||o.length||S.length>1||$?.density||d||f)?T(RB,{searchValue:OB,onSearchChange:r?y:void 0,searchPlaceholder:c?.placeholder??n("Search...",k)??"Search...",debounceMs:c?.debounceMs,activeChips:o,onClearAll:XB?()=>N?.({}):void 0,right:f,children:[d,S.length>1&&$?.viewMode!==!1?W(wB,{mode:_.mode,allowedModes:S,labels:i(B.view.kind)?$B?.labels:void 0,onChange:(Q)=>{if(Q===_.mode)return;if(F===void 0)UB(Q);HB?.(Q)}}):null,$?.density?W(FB,{density:P,onChange:(Q)=>{if(Q===P)return;if(h===void 0)YB(Q);JB?.(Q)}}):null,v?W(xB,{filters:B.view.filters,values:G.user,lockedKeys:Object.keys(G.locked),onFilterChange:N}):null]}):null,s,K&&K.total>0&&W(qB,{currentPage:K.page,totalPages:Math.ceil(K.total/K.pageSize),totalItems:K.total,itemsPerPage:K.pageSize,onPageChange:(Q)=>p?.(Q),onItemsPerPageChange:(Q)=>{p?.(1)},showItemsPerPage:!1})]})}function bB(B){if(!B)return;return Object.fromEntries(Object.entries(B??{}).filter((H)=>Boolean(H[1]&&typeof H[1]==="object"&&"kind"in H[1]&&typeof H[1].kind==="string")))}function a(B,H){return B.view.filters?.find((O)=>O.key===H)?.label??H}function l(B){if(!B)return"";if(B.kind==="single")return String(B.value);if(B.kind==="multi")return B.values.map(String).join(", ");if(B.kind==="range")return[B.from==null?"":String(B.from),B.to==null?"":String(B.to)].filter(Boolean).join(" - ");return`${B.mode}(${B.clauses.length})`}function xB({filters:B,values:H,lockedKeys:O,onFilterChange:U}){if(!B?.length||!U)return null;const J=new Set(O),Y=B.filter((Z)=>Z.type!=="search"&&!J.has(Z.key));if(Y.length===0)return null;return W("div",{className:"flex flex-wrap items-center gap-2",children:Y.map((Z)=>W(mB,{filter:Z,value:H[Z.key],values:H,onFilterChange:U},Z.key))})}function mB({filter:B,value:H,values:O,onFilterChange:U}){if(B.type==="boolean"){const J=H?.kind==="single"?H.value===!0:void 0;return T(V,{size:"sm",variant:"outline",onPress:()=>t(O,B.key,J===void 0?!0:!J,U),children:[B.label,": ",J?"Oui":"Non"]})}if(B.valueMode==="range"){const J=H?.kind==="range"?H:void 0;return T("div",{className:"flex min-w-0 items-center gap-2",children:[W(b,{type:x(B),inputMode:m(B),value:J?.from==null?"":String(J.from),onChange:(Y)=>e(O,B,"from",Y.currentTarget.value,U),placeholder:`${B.label} min`,className:"h-9 w-28"}),W(b,{type:x(B),inputMode:m(B),value:J?.to==null?"":String(J.to),onChange:(Y)=>e(O,B,"to",Y.currentTarget.value,U),placeholder:`${B.label} max`,className:"h-9 w-28"})]})}return W(b,{type:x(B),inputMode:m(B),value:H?.kind==="single"?String(H.value):"",onChange:(J)=>t(O,B.key,BB(B,J.currentTarget.value),U),placeholder:B.label,className:"h-9 w-36"})}function t(B,H,O,U){const J={...B};if(O===void 0||O==="")delete J[H];else J[H]={kind:"single",value:O};U(J)}function e(B,H,O,U,J){const Y=B[H.key],Z=Y?.kind==="range"?Y:{},A=BB(H,U),q={...Z,[O]:A};if(q.from==null&&q.to==null){const X={...B};delete X[H.key];J(X);return}J({...B,[H.key]:{kind:"range",from:q.from,to:q.to}})}function BB(B,H){if(H==="")return;switch(B.type){case"number":case"percent":case"currency":case"duration":{const O=Number(H);return Number.isFinite(O)?O:void 0}default:return H}}function x(B){switch(B.type){case"number":case"percent":case"currency":case"duration":return"number";case"date":return"date";case"time":return"time";case"datetime":return"datetime-local";default:return"text"}}function m(B){switch(B.type){case"number":case"percent":case"currency":case"duration":return"decimal";default:return}}function wB({mode:B,allowedModes:H,labels:O,onChange:U}){return W("div",{className:"flex items-center gap-1 rounded-md border bg-background p-1",children:H.map((J)=>{const Y=CB(J);return W(V,{size:"sm",variant:J===B?"default":"ghost",onPress:()=>U(J),ariaLabelI18n:O?.[J]??J,children:W(Y,{className:"h-4 w-4"})},J)})})}function FB({density:B,onChange:H}){return T("div",{className:"flex items-center gap-1 rounded-md border bg-background p-1",children:[W(V,{size:"sm",variant:B==="comfortable"?"default":"ghost",onPress:()=>H("comfortable"),children:"Comfort"}),W(V,{size:"sm",variant:B==="compact"?"default":"ghost",onPress:()=>H("compact"),children:"Compact"})]})}function CB(B){if(B==="grid")return IB;if(B==="table")return EB;return PB}
1
+ import{jsx as Y,jsxs as A,Fragment as sB}from"react/jsx-runtime";import{resolveDataViewFilters as EB}from"@contractspec/lib.contracts-spec/data-views";import{Pagination as NB}from"@contractspec/lib.ui-kit-web/ui/atoms/Pagination";import{VStack as RB}from"@contractspec/lib.ui-kit-web/ui/stack";import{Text as TB}from"@contractspec/lib.ui-kit-web/ui/text";import{Grid3X3 as AB,List as MB,Table2 as jB}from"lucide-react";import*as q from"react";import{resolveTranslationString as a,useDesignSystemTranslation as kB}from"../../i18n/translation";import{Button as T}from"../atoms/Button";import{Input as F}from"../atoms/Input";import{FiltersToolbar as VB}from"../molecules/FiltersToolbar";import{DATA_VIEW_DATA_DEPTHS as _B,formatDataViewDataDepth as SB,getDataViewCollectionConfig as bB,getDataViewCollectionViewModesConfig as xB,isDataViewCollectionKind as t,projectCollectionDataDepth as FB,resolveAllowedCollectionModes as wB,resolveCollectionDataDepth as mB,resolveCollectionDensity as CB,resolveCollectionView as DB}from"./collection";import{DataViewDetail as yB}from"./DataViewDetail";import{DataViewGrid as gB}from"./DataViewGrid";import{DataViewList as hB}from"./DataViewList";import{DataViewTable as uB}from"./DataViewTable";export function DataViewRenderer({spec:B,items:J=[],item:Q=null,className:Z,renderActions:O,onSelect:$,onRowClick:H,toolbar:M,loading:K,headerActions:X,emptyState:E,footer:C,viewMode:D,defaultViewMode:y,onViewModeChange:UB,density:g,defaultDensity:h,onDensityChange:YB,dataDepth:u,defaultDataDepth:v,onDataDepthChange:ZB,search:$B,onSearchChange:d,filters:z,onFilterChange:N,pagination:L,onPageChange:p}){const S=kB(),b=q.useMemo(()=>wB(B.view),[B.view]),[HB,WB]=q.useState(y),f=D??HB??y,j=q.useMemo(()=>DB(B,f),[f,B]),[XB,zB]=q.useState(h),P=CB(B,{density:g??XB,defaultDensity:h}),[GB,qB]=q.useState(v),k=mB(B,{dataDepth:u??GB,defaultDataDepth:v}),KB=bB(B.view),LB=xB(B.view),W=KB?.toolbar,V=W?.enabled!==!1,c=W?.filters!==!1,_=W?.actions??"end",r=_==="start"||_==="both"?X:void 0,o=_==="end"||_==="both"?X:void 0,s=typeof W?.search==="object"?W.search:void 0,n=Boolean(V&&W?.search!==!1&&d),G=q.useMemo(()=>EB({filters:B.view.filters,scope:B.view.filterScope,user:vB(z)}),[z,B.view.filterScope,B.view.filters]),i=q.useMemo(()=>{if(B.view.filterScope){const U=Object.entries(G.user).map(([I,R])=>({key:I,label:`${e(B,I)}: ${BB(R)}`,onRemove:()=>{const{[I]:iB,...PB}=G.user;N?.(PB)}})),x=G.lockedChips==="hidden"?[]:Object.entries(G.locked).map(([I,R])=>({key:`locked-${I}`,label:`${e(B,I)}: ${BB(R)}`,disabled:!0}));return[...U,...x]}return z?Object.entries(z).map(([U,x])=>({key:U,label:`${U}: ${String(x)}`,onRemove:()=>{const{[U]:I,...R}=z;N?.(R)}})):[]},[z,N,G,B]),IB=B.view.filterScope?Object.keys(G.user).length>0:Boolean(z&&Object.keys(z).length>0),l=q.useMemo(()=>{const U=t(B.view.kind)?FB(j.spec,k):B;switch(U.view.kind){case"list":return Y(hB,{spec:U,items:J,className:Z,renderActions:O,onSelect:$,emptyState:E,density:P});case"table":return Y(uB,{spec:U,items:J,className:Z,onRowClick:H,toolbar:M,loading:K,emptyState:E,headerActions:V?void 0:X,footer:C,density:P});case"detail":return Y(yB,{spec:B,item:Q,className:Z,emptyState:E,headerActions:X});case"grid":return Y(gB,{spec:U,items:J,className:Z,renderActions:O,onSelect:$,emptyState:E,density:P});default:return Y(TB,{className:Z,children:a("Unsupported data view kind",S)})}},[B,j.spec,J,Q,Z,O,$,H,M,K,X,E,C,P,k,V,S]);if(!(B.view.kind==="list"||B.view.kind==="table"||B.view.kind==="grid"))return Y(sB,{children:l});return A(RB,{gap:"lg",children:[V&&(c&&B.view.filters?.length||n||i.length||b.length>1||W?.density||W?.dataDepth||r||o)?A(VB,{searchValue:$B,onSearchChange:n?d:void 0,searchPlaceholder:s?.placeholder??a("Search...",S)??"Search...",debounceMs:s?.debounceMs,activeChips:i,onClearAll:IB?()=>N?.({}):void 0,right:o,children:[r,b.length>1&&W?.viewMode!==!1?Y(fB,{mode:j.mode,allowedModes:b,labels:t(B.view.kind)?LB?.labels:void 0,onChange:(U)=>{if(U===j.mode)return;if(D===void 0)WB(U);UB?.(U)}}):null,W?.density?Y(cB,{density:P,onChange:(U)=>{if(U===P)return;if(g===void 0)zB(U);YB?.(U)}}):null,W?.dataDepth?Y(rB,{dataDepth:k,onChange:(U)=>{if(U===k)return;if(u===void 0)qB(U);ZB?.(U)}}):null,c?Y(dB,{filters:B.view.filters,values:G.user,lockedKeys:Object.keys(G.locked),onFilterChange:N}):null]}):null,l,L&&L.total>0&&Y(NB,{currentPage:L.page,totalPages:Math.ceil(L.total/L.pageSize),totalItems:L.total,itemsPerPage:L.pageSize,onPageChange:(U)=>p?.(U),onItemsPerPageChange:(U)=>{p?.(1)},showItemsPerPage:!1})]})}function vB(B){if(!B)return;return Object.fromEntries(Object.entries(B??{}).filter((J)=>Boolean(J[1]&&typeof J[1]==="object"&&"kind"in J[1]&&typeof J[1].kind==="string")))}function e(B,J){return B.view.filters?.find((Q)=>Q.key===J)?.label??J}function BB(B){if(!B)return"";if(B.kind==="single")return String(B.value);if(B.kind==="multi")return B.values.map(String).join(", ");if(B.kind==="range")return[B.from==null?"":String(B.from),B.to==null?"":String(B.to)].filter(Boolean).join(" - ");return`${B.mode}(${B.clauses.length})`}function dB({filters:B,values:J,lockedKeys:Q,onFilterChange:Z}){if(!B?.length||!Z)return null;const O=new Set(Q),$=B.filter((H)=>H.type!=="search"&&!O.has(H.key));if($.length===0)return null;return Y("div",{className:"flex flex-wrap items-center gap-2",children:$.map((H)=>Y(pB,{filter:H,value:J[H.key],values:J,onFilterChange:Z},H.key))})}function pB({filter:B,value:J,values:Q,onFilterChange:Z}){if(B.type==="boolean"){const O=J?.kind==="single"?J.value===!0:void 0;return A(T,{size:"sm",variant:"outline",onPress:()=>JB(Q,B.key,O===void 0?!0:!O,Z),children:[B.label,": ",O?"Oui":"Non"]})}if(B.valueMode==="range"){const O=J?.kind==="range"?J:void 0;return A("div",{className:"flex min-w-0 items-center gap-2",children:[Y(F,{type:w(B),inputMode:m(B),value:O?.from==null?"":String(O.from),onChange:($)=>OB(Q,B,"from",$.currentTarget.value,Z),placeholder:`${B.label} min`,className:"h-9 w-28"}),Y(F,{type:w(B),inputMode:m(B),value:O?.to==null?"":String(O.to),onChange:($)=>OB(Q,B,"to",$.currentTarget.value,Z),placeholder:`${B.label} max`,className:"h-9 w-28"})]})}return Y(F,{type:w(B),inputMode:m(B),value:J?.kind==="single"?String(J.value):"",onChange:(O)=>JB(Q,B.key,QB(B,O.currentTarget.value),Z),placeholder:B.label,className:"h-9 w-36"})}function JB(B,J,Q,Z){const O={...B};if(Q===void 0||Q==="")delete O[J];else O[J]={kind:"single",value:Q};Z(O)}function OB(B,J,Q,Z,O){const $=B[J.key],H=$?.kind==="range"?$:{},M=QB(J,Z),K={...H,[Q]:M};if(K.from==null&&K.to==null){const X={...B};delete X[J.key];O(X);return}O({...B,[J.key]:{kind:"range",from:K.from,to:K.to}})}function QB(B,J){if(J==="")return;switch(B.type){case"number":case"percent":case"currency":case"duration":{const Q=Number(J);return Number.isFinite(Q)?Q:void 0}default:return J}}function w(B){switch(B.type){case"number":case"percent":case"currency":case"duration":return"number";case"date":return"date";case"time":return"time";case"datetime":return"datetime-local";default:return"text"}}function m(B){switch(B.type){case"number":case"percent":case"currency":case"duration":return"decimal";default:return}}function fB({mode:B,allowedModes:J,labels:Q,onChange:Z}){return Y("div",{className:"flex items-center gap-1 rounded-md border bg-background p-1",children:J.map((O)=>{const $=oB(O);return Y(T,{size:"sm",variant:O===B?"default":"ghost",onPress:()=>Z(O),ariaLabelI18n:Q?.[O]??O,children:Y($,{className:"h-4 w-4"})},O)})})}function cB({density:B,onChange:J}){return A("div",{className:"flex items-center gap-1 rounded-md border bg-background p-1",children:[Y(T,{size:"sm",variant:B==="comfortable"?"default":"ghost",onPress:()=>J("comfortable"),children:"Comfort"}),Y(T,{size:"sm",variant:B==="compact"?"default":"ghost",onPress:()=>J("compact"),children:"Compact"})]})}function rB({dataDepth:B,onChange:J}){return Y("div",{className:"flex items-center gap-1 rounded-md border bg-background p-1",children:_B.map((Q)=>Y(T,{size:"sm",variant:B===Q?"default":"ghost",onPress:()=>J(Q),children:SB(Q)},Q))})}function oB(B){if(B==="grid")return AB;if(B==="table")return jB;return MB}
@@ -1 +1 @@
1
- import{jsx as X,jsxs as R,Fragment as xB}from"react/jsx-runtime";import{resolveDataViewFilters as KB}from"@contractspec/lib.contracts-spec/data-views";import{Pagination as qB}from"@contractspec/lib.ui-kit/ui/atoms/Pagination";import{HStack as D,VStack as HB}from"@contractspec/lib.ui-kit/ui/stack";import{Text as IB}from"@contractspec/lib.ui-kit/ui/text";import*as I from"react";import{resolveTranslationString as n,useDesignSystemTranslation as PB}from"../../i18n/translation";import{Button as k}from"../atoms/Button";import{Input as F}from"../atoms/Input";import{FiltersToolbar as EB}from"../molecules/FiltersToolbar";import{getDataViewCollectionConfig as NB,getDataViewCollectionViewModesConfig as TB,isDataViewCollectionKind as l,resolveAllowedCollectionModes as RB,resolveCollectionDensity as AB,resolveCollectionView as _B}from"./collection";import{DataViewDetail as jB}from"./DataViewDetail";import{DataViewGrid as MB}from"./DataViewGrid";import{DataViewList as DB}from"./DataViewList";import{DataViewTable as kB}from"./DataViewTable";export function DataViewRenderer({spec:B,items:J=[],item:Q=null,className:W,renderActions:O,onSelect:Y,onRowClick:Z,toolbar:A,loading:K,headerActions:G,emptyState:E,footer:w,viewMode:C,defaultViewMode:h,onViewModeChange:OB,density:y,defaultDensity:g,onDensityChange:QB,search:UB,onSearchChange:p,filters:L,onFilterChange:N,pagination:q,onPageChange:v}){const S=PB(),V=I.useMemo(()=>RB(B.view),[B.view]),[WB,XB]=I.useState(h),d=C??WB??h,_=I.useMemo(()=>_B(B,d),[d,B]),[YB,ZB]=I.useState(g),P=AB(B,{density:y??YB,defaultDensity:g}),$B=NB(B.view),GB=TB(B.view),$=$B?.toolbar,j=$?.enabled!==!1,u=$?.filters!==!1,M=$?.actions??"end",f=M==="start"||M==="both"?G:void 0,c=M==="end"||M==="both"?G:void 0,r=typeof $?.search==="object"?$.search:void 0,o=Boolean(j&&$?.search!==!1&&p),z=I.useMemo(()=>KB({filters:B.view.filters,scope:B.view.filterScope,user:SB(L)}),[L,B.view.filterScope,B.view.filters]),s=I.useMemo(()=>{if(B.view.filterScope){const U=Object.entries(z.user).map(([H,T])=>({key:H,label:`${a(B,H)}: ${t(T)}`,onRemove:()=>{const{[H]:CB,...zB}=z.user;N?.(zB)}})),b=z.lockedChips==="hidden"?[]:Object.entries(z.locked).map(([H,T])=>({key:`locked-${H}`,label:`${a(B,H)}: ${t(T)}`,disabled:!0}));return[...U,...b]}return L?Object.entries(L).map(([U,b])=>({key:U,label:`${U}: ${String(b)}`,onRemove:()=>{const{[U]:H,...T}=L;N?.(T)}})):[]},[L,N,z,B]),LB=B.view.filterScope?Object.keys(z.user).length>0:Boolean(L&&Object.keys(L).length>0),i=I.useMemo(()=>{const U=l(B.view.kind)?_.spec:B;switch(U.view.kind){case"list":return X(DB,{spec:U,items:J,className:W,renderActions:O,onSelect:Y,emptyState:E,density:P});case"table":return X(kB,{spec:U,items:J,className:W,onRowClick:Z,toolbar:A,loading:K,emptyState:E,headerActions:j?void 0:G,footer:w,density:P});case"detail":return X(jB,{spec:B,item:Q,className:W,emptyState:E,headerActions:G});case"grid":return X(MB,{spec:U,items:J,className:W,renderActions:O,onSelect:Y,emptyState:E,density:P});default:return X(IB,{className:W,children:n("Unsupported data view kind",S)})}},[B,_.spec,J,Q,W,O,Y,Z,A,K,G,E,w,P,j,S]);if(!(B.view.kind==="list"||B.view.kind==="table"||B.view.kind==="grid"))return X(xB,{children:i});return R(HB,{gap:"lg",children:[j&&(u&&B.view.filters?.length||o||s.length||V.length>1||$?.density||f||c)?R(EB,{searchValue:UB,onSearchChange:o?p:void 0,searchPlaceholder:r?.placeholder??n("Search...",S)??"Search...",debounceMs:r?.debounceMs,activeChips:s,onClearAll:LB?()=>N?.({}):void 0,right:c,children:[f,V.length>1&&$?.viewMode!==!1?X(FB,{mode:_.mode,allowedModes:V,labels:l(B.view.kind)?GB?.labels:void 0,onChange:(U)=>{if(U===_.mode)return;if(C===void 0)XB(U);OB?.(U)}}):null,$?.density?X(mB,{density:P,onChange:(U)=>{if(U===P)return;if(y===void 0)ZB(U);QB?.(U)}}):null,u?X(VB,{filters:B.view.filters,values:z.user,lockedKeys:Object.keys(z.locked),onFilterChange:N}):null]}):null,i,q&&q.total>0?X(qB,{currentPage:q.page,totalPages:Math.ceil(q.total/q.pageSize),totalItems:q.total,itemsPerPage:q.pageSize,onPageChange:(U)=>v?.(U),onItemsPerPageChange:(U)=>{v?.(1)},showItemsPerPage:!1}):null]})}function SB(B){if(!B)return;return Object.fromEntries(Object.entries(B??{}).filter((J)=>Boolean(J[1]&&typeof J[1]==="object"&&"kind"in J[1]&&typeof J[1].kind==="string")))}function a(B,J){return B.view.filters?.find((Q)=>Q.key===J)?.label??J}function t(B){if(!B)return"";if(B.kind==="single")return String(B.value);if(B.kind==="multi")return B.values.map(String).join(", ");if(B.kind==="range")return[B.from==null?"":String(B.from),B.to==null?"":String(B.to)].filter(Boolean).join(" - ");return`${B.mode}(${B.clauses.length})`}function VB({filters:B,values:J,lockedKeys:Q,onFilterChange:W}){if(!B?.length||!W)return null;const O=new Set(Q),Y=B.filter((Z)=>Z.type!=="search"&&!O.has(Z.key));if(Y.length===0)return null;return X(D,{className:"flex flex-wrap items-center gap-2",children:Y.map((Z)=>X(bB,{filter:Z,value:J[Z.key],values:J,onFilterChange:W},Z.key))})}function bB({filter:B,value:J,values:Q,onFilterChange:W}){if(B.type==="boolean"){const O=J?.kind==="single"?J.value===!0:void 0;return R(k,{size:"sm",variant:"outline",onPress:()=>e(Q,B.key,O===void 0?!0:!O,W),children:[B.label,": ",O?"Oui":"Non"]})}if(B.valueMode==="range"){const O=J?.kind==="range"?J:void 0;return R(D,{className:"items-center gap-2",children:[X(F,{value:O?.from==null?"":String(O.from),onChange:(Y)=>BB(Q,B,"from",x(Y),W),placeholder:`${B.label} min`,keyboard:m(B),className:"h-9 w-28"}),X(F,{value:O?.to==null?"":String(O.to),onChange:(Y)=>BB(Q,B,"to",x(Y),W),placeholder:`${B.label} max`,keyboard:m(B),className:"h-9 w-28"})]})}return X(F,{value:J?.kind==="single"?String(J.value):"",onChange:(O)=>e(Q,B.key,JB(B,x(O)),W),placeholder:B.label,keyboard:m(B),className:"h-9 w-36"})}function e(B,J,Q,W){const O={...B};if(Q===void 0||Q==="")delete O[J];else O[J]={kind:"single",value:Q};W(O)}function BB(B,J,Q,W,O){const Y=B[J.key],Z=Y?.kind==="range"?Y:{},A=JB(J,W),K={...Z,[Q]:A};if(K.from==null&&K.to==null){const G={...B};delete G[J.key];O(G);return}O({...B,[J.key]:{kind:"range",from:K.from,to:K.to}})}function JB(B,J){if(J==="")return;switch(B.type){case"number":case"percent":case"currency":case"duration":{const Q=Number(J);return Number.isFinite(Q)?Q:void 0}default:return J}}function m(B){switch(B.type){case"number":case"percent":case"currency":case"duration":return{kind:"decimal"};default:return}}function x(B){return typeof B==="string"?B:B.currentTarget.value}function FB({mode:B,allowedModes:J,labels:Q,onChange:W}){return X(D,{className:"items-center gap-1",children:J.map((O)=>X(k,{size:"sm",variant:O===B?"default":"ghost",onPress:()=>W(O),children:Q?.[O]??O},O))})}function mB({density:B,onChange:J}){return R(D,{className:"items-center gap-1",children:[X(k,{size:"sm",variant:B==="comfortable"?"default":"ghost",onPress:()=>J("comfortable"),children:"Comfort"}),X(k,{size:"sm",variant:B==="compact"?"default":"ghost",onPress:()=>J("compact"),children:"Compact"})]})}
1
+ import{jsx as X,jsxs as M,Fragment as cB}from"react/jsx-runtime";import{resolveDataViewFilters as NB}from"@contractspec/lib.contracts-spec/data-views";import{Pagination as RB}from"@contractspec/lib.ui-kit/ui/atoms/Pagination";import{HStack as T,VStack as TB}from"@contractspec/lib.ui-kit/ui/stack";import{Text as AB}from"@contractspec/lib.ui-kit/ui/text";import*as L from"react";import{resolveTranslationString as t,useDesignSystemTranslation as MB}from"../../i18n/translation";import{Button as A}from"../atoms/Button";import{Input as x}from"../atoms/Input";import{FiltersToolbar as jB}from"../molecules/FiltersToolbar";import{DATA_VIEW_DATA_DEPTHS as _B,formatDataViewDataDepth as kB,getDataViewCollectionConfig as SB,getDataViewCollectionViewModesConfig as VB,isDataViewCollectionKind as e,projectCollectionDataDepth as bB,resolveAllowedCollectionModes as FB,resolveCollectionDataDepth as mB,resolveCollectionDensity as xB,resolveCollectionView as wB}from"./collection";import{DataViewDetail as CB}from"./DataViewDetail";import{DataViewGrid as DB}from"./DataViewGrid";import{DataViewList as yB}from"./DataViewList";import{DataViewTable as gB}from"./DataViewTable";export function DataViewRenderer({spec:B,items:J=[],item:Q=null,className:Y,renderActions:O,onSelect:Z,onRowClick:$,toolbar:j,loading:K,headerActions:W,emptyState:E,footer:D,viewMode:y,defaultViewMode:g,onViewModeChange:XB,density:h,defaultDensity:v,onDensityChange:YB,dataDepth:u,defaultDataDepth:d,onDataDepthChange:ZB,search:$B,onSearchChange:p,filters:z,onFilterChange:N,pagination:H,onPageChange:f}){const b=MB(),F=L.useMemo(()=>FB(B.view),[B.view]),[GB,WB]=L.useState(g),c=y??GB??g,_=L.useMemo(()=>wB(B,c),[c,B]),[zB,qB]=L.useState(v),P=xB(B,{density:h??zB,defaultDensity:v}),[LB,KB]=L.useState(d),k=mB(B,{dataDepth:u??LB,defaultDataDepth:d}),HB=SB(B.view),IB=VB(B.view),G=HB?.toolbar,S=G?.enabled!==!1,r=G?.filters!==!1,V=G?.actions??"end",o=V==="start"||V==="both"?W:void 0,s=V==="end"||V==="both"?W:void 0,n=typeof G?.search==="object"?G.search:void 0,i=Boolean(S&&G?.search!==!1&&p),q=L.useMemo(()=>NB({filters:B.view.filters,scope:B.view.filterScope,user:hB(z)}),[z,B.view.filterScope,B.view.filters]),l=L.useMemo(()=>{if(B.view.filterScope){const U=Object.entries(q.user).map(([I,R])=>({key:I,label:`${BB(B,I)}: ${JB(R)}`,onRemove:()=>{const{[I]:oB,...EB}=q.user;N?.(EB)}})),m=q.lockedChips==="hidden"?[]:Object.entries(q.locked).map(([I,R])=>({key:`locked-${I}`,label:`${BB(B,I)}: ${JB(R)}`,disabled:!0}));return[...U,...m]}return z?Object.entries(z).map(([U,m])=>({key:U,label:`${U}: ${String(m)}`,onRemove:()=>{const{[U]:I,...R}=z;N?.(R)}})):[]},[z,N,q,B]),PB=B.view.filterScope?Object.keys(q.user).length>0:Boolean(z&&Object.keys(z).length>0),a=L.useMemo(()=>{const U=e(B.view.kind)?bB(_.spec,k):B;switch(U.view.kind){case"list":return X(yB,{spec:U,items:J,className:Y,renderActions:O,onSelect:Z,emptyState:E,density:P});case"table":return X(gB,{spec:U,items:J,className:Y,onRowClick:$,toolbar:j,loading:K,emptyState:E,headerActions:S?void 0:W,footer:D,density:P});case"detail":return X(CB,{spec:B,item:Q,className:Y,emptyState:E,headerActions:W});case"grid":return X(DB,{spec:U,items:J,className:Y,renderActions:O,onSelect:Z,emptyState:E,density:P});default:return X(AB,{className:Y,children:t("Unsupported data view kind",b)})}},[B,_.spec,J,Q,Y,O,Z,$,j,K,W,E,D,P,k,S,b]);if(!(B.view.kind==="list"||B.view.kind==="table"||B.view.kind==="grid"))return X(cB,{children:a});return M(TB,{gap:"lg",children:[S&&(r&&B.view.filters?.length||i||l.length||F.length>1||G?.density||G?.dataDepth||o||s)?M(jB,{searchValue:$B,onSearchChange:i?p:void 0,searchPlaceholder:n?.placeholder??t("Search...",b)??"Search...",debounceMs:n?.debounceMs,activeChips:l,onClearAll:PB?()=>N?.({}):void 0,right:s,children:[o,F.length>1&&G?.viewMode!==!1?X(dB,{mode:_.mode,allowedModes:F,labels:e(B.view.kind)?IB?.labels:void 0,onChange:(U)=>{if(U===_.mode)return;if(y===void 0)WB(U);XB?.(U)}}):null,G?.density?X(pB,{density:P,onChange:(U)=>{if(U===P)return;if(h===void 0)qB(U);YB?.(U)}}):null,G?.dataDepth?X(fB,{dataDepth:k,onChange:(U)=>{if(U===k)return;if(u===void 0)KB(U);ZB?.(U)}}):null,r?X(vB,{filters:B.view.filters,values:q.user,lockedKeys:Object.keys(q.locked),onFilterChange:N}):null]}):null,a,H&&H.total>0?X(RB,{currentPage:H.page,totalPages:Math.ceil(H.total/H.pageSize),totalItems:H.total,itemsPerPage:H.pageSize,onPageChange:(U)=>f?.(U),onItemsPerPageChange:(U)=>{f?.(1)},showItemsPerPage:!1}):null]})}function hB(B){if(!B)return;return Object.fromEntries(Object.entries(B??{}).filter((J)=>Boolean(J[1]&&typeof J[1]==="object"&&"kind"in J[1]&&typeof J[1].kind==="string")))}function BB(B,J){return B.view.filters?.find((Q)=>Q.key===J)?.label??J}function JB(B){if(!B)return"";if(B.kind==="single")return String(B.value);if(B.kind==="multi")return B.values.map(String).join(", ");if(B.kind==="range")return[B.from==null?"":String(B.from),B.to==null?"":String(B.to)].filter(Boolean).join(" - ");return`${B.mode}(${B.clauses.length})`}function vB({filters:B,values:J,lockedKeys:Q,onFilterChange:Y}){if(!B?.length||!Y)return null;const O=new Set(Q),Z=B.filter(($)=>$.type!=="search"&&!O.has($.key));if(Z.length===0)return null;return X(T,{className:"flex flex-wrap items-center gap-2",children:Z.map(($)=>X(uB,{filter:$,value:J[$.key],values:J,onFilterChange:Y},$.key))})}function uB({filter:B,value:J,values:Q,onFilterChange:Y}){if(B.type==="boolean"){const O=J?.kind==="single"?J.value===!0:void 0;return M(A,{size:"sm",variant:"outline",onPress:()=>OB(Q,B.key,O===void 0?!0:!O,Y),children:[B.label,": ",O?"Oui":"Non"]})}if(B.valueMode==="range"){const O=J?.kind==="range"?J:void 0;return M(T,{className:"items-center gap-2",children:[X(x,{value:O?.from==null?"":String(O.from),onChange:(Z)=>QB(Q,B,"from",C(Z),Y),placeholder:`${B.label} min`,keyboard:w(B),className:"h-9 w-28"}),X(x,{value:O?.to==null?"":String(O.to),onChange:(Z)=>QB(Q,B,"to",C(Z),Y),placeholder:`${B.label} max`,keyboard:w(B),className:"h-9 w-28"})]})}return X(x,{value:J?.kind==="single"?String(J.value):"",onChange:(O)=>OB(Q,B.key,UB(B,C(O)),Y),placeholder:B.label,keyboard:w(B),className:"h-9 w-36"})}function OB(B,J,Q,Y){const O={...B};if(Q===void 0||Q==="")delete O[J];else O[J]={kind:"single",value:Q};Y(O)}function QB(B,J,Q,Y,O){const Z=B[J.key],$=Z?.kind==="range"?Z:{},j=UB(J,Y),K={...$,[Q]:j};if(K.from==null&&K.to==null){const W={...B};delete W[J.key];O(W);return}O({...B,[J.key]:{kind:"range",from:K.from,to:K.to}})}function UB(B,J){if(J==="")return;switch(B.type){case"number":case"percent":case"currency":case"duration":{const Q=Number(J);return Number.isFinite(Q)?Q:void 0}default:return J}}function w(B){switch(B.type){case"number":case"percent":case"currency":case"duration":return{kind:"decimal"};default:return}}function C(B){return typeof B==="string"?B:B.currentTarget.value}function dB({mode:B,allowedModes:J,labels:Q,onChange:Y}){return X(T,{className:"items-center gap-1",children:J.map((O)=>X(A,{size:"sm",variant:O===B?"default":"ghost",onPress:()=>Y(O),children:Q?.[O]??O},O))})}function pB({density:B,onChange:J}){return M(T,{className:"items-center gap-1",children:[X(A,{size:"sm",variant:B==="comfortable"?"default":"ghost",onPress:()=>J("comfortable"),children:"Comfort"}),X(A,{size:"sm",variant:B==="compact"?"default":"ghost",onPress:()=>J("compact"),children:"Compact"})]})}function fB({dataDepth:B,onChange:J}){return X(T,{className:"items-center gap-1",children:_B.map((Q)=>X(A,{size:"sm",variant:B===Q?"default":"ghost",onPress:()=>J(Q),children:kB(Q)},Q))})}