@sybilion/uilib 1.0.31 → 1.1.0

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.
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Default chart margins
3
+ */
4
+ const CHART_MARGINS = {
5
+ top: 20,
6
+ right: 30,
7
+ bottom: 20,
8
+ left: -10,
9
+ };
10
+
11
+ export { CHART_MARGINS };
@@ -5,6 +5,7 @@ import { BaseChartWrapper } from '../Chart/components/BaseChartWrapper.js';
5
5
  import { InteractionOverlay } from '../InteractionOverlay/InteractionOverlay.js';
6
6
  import { TimeRangeControls } from '../TimeRangeControls/TimeRangeControls.js';
7
7
  import { ensureChartForecastBridge } from '../../../utils/chartConnectionPoint.js';
8
+ import { CHART_MARGINS } from './ChartAreaInteractive.constants.js';
8
9
  import { filterDataForTimeRange, shortDateFormatter, longDateFormatter } from './ChartAreaInteractive.helpers.js';
9
10
  import S from './ChartAreaInteractive.styl.js';
10
11
  import { PinOverlay } from './overlays/PinOverlay/PinOverlay.js';
@@ -80,7 +81,7 @@ function ChartAreaInteractive({ className, chartContainerClassName, legendClassN
80
81
  formatDate: shortDateFormatter,
81
82
  labelFormatter: (v) => longDateFormatter(v),
82
83
  chartType: 'composed',
83
- margin: { left: -10, right: 30, top: 20, bottom: 20 },
84
+ margin: { ...CHART_MARGINS },
84
85
  hiddenSeries: seriesHidden,
85
86
  onLegendClick: handleLegendClick,
86
87
  onAnalysisSelect: onAnalysisSelect,
@@ -392,17 +392,10 @@ function SidebarContent({ className, innerClassName, children, }) {
392
392
  function SidebarGroup({ className, ...props }) {
393
393
  return (jsx("div", { "data-slot": "sidebar-group", "data-sidebar": "group", className: cn(SidebarStem.sidebarGroup, className), ...props }));
394
394
  }
395
- function SidebarGroupLabel({ className, asChild = false, ...props }) {
396
- const Comp = asChild ? Slot : 'div';
397
- return (jsx(Comp, { "data-slot": "sidebar-group-label", "data-sidebar": "group-label", className: cn(SidebarStem.sidebarGroupLabel, className), ...props }));
398
- }
399
395
  function SidebarGroupAction({ className, asChild = false, ...props }) {
400
396
  const Comp = asChild ? Slot : 'button';
401
397
  return (jsx(Comp, { "data-slot": "sidebar-group-action", "data-sidebar": "group-action", className: cn(SidebarStem.sidebarGroupAction, className), ...props }));
402
398
  }
403
- function SidebarGroupContent({ className, ...props }) {
404
- return (jsx("div", { "data-slot": "sidebar-group-content", "data-sidebar": "group-content", className: cn(SidebarStem.sidebarGroupContent, className), ...props }));
405
- }
406
399
  function SidebarMenu({ className, ...props }) {
407
400
  return (jsx("ul", { "data-slot": "sidebar-menu", "data-sidebar": "menu", className: cn(SidebarStem.sidebarMenu, className), ...props }));
408
401
  }
@@ -445,4 +438,4 @@ function SidebarMenuSubButton({ asChild = false, size = 'md', isActive = false,
445
438
  return (jsxs(Tooltip, { children: [jsx(TooltipTrigger, { asChild: true, children: button }), jsx(TooltipContent, { side: "right", align: "center", hidden: !isOpen || isMobile, ...tooltip })] }));
446
439
  }
447
440
 
448
- export { PanelResizeHandle, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarResizeHandle, SidebarSeparator, SidebarTrigger, useSidebar };
441
+ export { PanelResizeHandle, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarResizeHandle, SidebarSeparator, SidebarTrigger, useSidebar };
@@ -1,7 +1,7 @@
1
1
  import styleInject from 'style-inject';
2
2
 
3
- var css_248z = "@media (max-width:768px){:root{--page-x-padding:var(--p-6);--page-y-padding:var(--p-6)}}.Sidebar_sidebarWrapper__DGm4P{align-items:stretch;display:flex;flex-direction:row;--welcome-alert-height:44px;height:calc(100% - 44px);height:calc(100% - var(--welcome-alert-height));min-height:0;width:100%}.Sidebar_sidebarWrapper__DGm4P #page-sidebar-actions{min-height:100%}@media (max-width:768px){.Sidebar_sidebarWrapper__DGm4P{flex-direction:column;height:100dvh;max-height:100dvh}}.Sidebar_sidebarMainShell__pSWDC{display:flex;flex:1;flex-direction:column;min-height:0;min-width:0}.Sidebar_chatPanelMount__1Zctx{background:var(--background);border-left:1px solid var(--border);flex:0 0 0px;flex:0 0 var(--chat-panel-width,0px);min-height:0;min-width:0;overflow:hidden;width:0;width:var(--chat-panel-width,0)}@media (max-width:768px){.Sidebar_chatPanelMount__1Zctx{border-left:none;border-top:1px solid var(--border);flex:0 0 0px;flex:0 0 var(--chat-panel-height,0px);height:0;height:var(--chat-panel-height,0);transition:flex-basis .2s ease,height .2s ease;width:100%}}.Sidebar_sidebar__0vqNZ{height:0;position:fixed;--top-offset:-10px;--gap-top:calc(var(--header-height) + var(--top-offset));align-self:flex-start;color:var(--sidebar-foreground);display:none;flex-direction:column;top:var(--gap-top);width:var(--sidebar-width)}@media (min-width:768px){.Sidebar_sidebar__0vqNZ[data-state=expanded]{display:flex;height:calc(100vh - var(--gap-top));min-height:0}}.Sidebar_sidebar__0vqNZ[data-collapsible=offcanvas]{overflow:hidden;padding:0;width:0}.Sidebar_sidebarTrigger__ipx2C{cursor:pointer;height:var(--p-5);width:var(--p-5)}.Sidebar_sidebarTrigger__ipx2C svg{height:20px;width:20px}.Sidebar_sidebarRail__uvSpl{position:absolute;inset-y:0;display:hidden;transition:all ease-out;width:1rem;z-index:20}.Sidebar_sidebarRail__uvSpl:hover:after{background-color:var(--sidebar-border)}.Sidebar_sidebarRail__uvSpl[data-side=left]{right:-1rem}.Sidebar_sidebarRail__uvSpl[data-side=right]{left:0}.Sidebar_sidebarRail__uvSpl:after{content:\"\";position:absolute;inset-y:0;left:50%;width:2px}@media (min-width:640px){.Sidebar_sidebarRail__uvSpl{display:flex}}.Sidebar_sidebarRail__uvSpl[data-side=left]{cursor:w-resize}.Sidebar_sidebarRail__uvSpl[data-side=left][data-state=collapsed],.Sidebar_sidebarRail__uvSpl[data-side=right]{cursor:e-resize}.Sidebar_sidebarRail__uvSpl[data-side=right][data-state=collapsed]{cursor:w-resize}.Sidebar_sidebarRail__uvSpl[data-collapsible=offcanvas]{transform:translateX(0)}.Sidebar_sidebarRail__uvSpl[data-collapsible=offcanvas]:hover{background-color:var(--sidebar)}.Sidebar_sidebarRail__uvSpl[data-collapsible=offcanvas]:after{left:100%}.Sidebar_sidebarRail__uvSpl[data-side=left][data-collapsible=offcanvas]{right:-.5rem}.Sidebar_sidebarRail__uvSpl[data-side=right][data-collapsible=offcanvas]{left:-.5rem}.Sidebar_sidebarResizeHandle__kuD6t{background-color:transparent;background-color:var(--page-color);border-radius:2.5px;height:calc(100vh + 200px);opacity:0;position:absolute;top:-200px;touch-action:none;transition:opacity .15s ease-out;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:5px;z-index:30}.Sidebar_sidebarResizeHandle__kuD6t:before{content:\"\";cursor:col-resize;height:100%;position:absolute;right:0;width:30px}.Sidebar_sidebarResizeHandle__kuD6t[data-side=left]{right:2px}.Sidebar_sidebarResizeHandle__kuD6t[data-side=right]{left:0}.Sidebar_sidebarResizeHandle__kuD6t:hover{opacity:1}.Sidebar_sidebarResizeHandle__kuD6t:active{opacity:0}.Sidebar_fullHeightResizer__jZXnw .Sidebar_sidebarResizeHandle__kuD6t{height:calc(100vh - var(--gap-top)*-1);top:-80px}.Sidebar_sidebarInput__ujQLX{background-color:var(--background);box-shadow:none;height:2rem;width:100%}.Sidebar_sidebarFooter__V3O-l,.Sidebar_sidebarHeader__X33ii{display:flex;flex-direction:column;gap:0;padding:0}.Sidebar_sidebarSeparator__oUkYG{background-color:var(--sidebar-border);margin-left:0;margin-right:0;width:auto}.Sidebar_sidebarContent__Ywe1o{display:flex;flex:1;flex-direction:column;gap:var(--p-16);height:100vh;max-height:100vh;min-height:0;overflow:auto;position:absolute;width:100%}@media (min-width:768px){.Sidebar_sidebarContent__Ywe1o{height:calc(100vh - var(--gap-top))}}.Sidebar_sidebarContent__Ywe1o[data-collapsible=icon]{overflow:hidden}.Sidebar_sidebarGroup__7Mhg2{display:flex;flex-direction:column;min-width:0;padding:40px 0 0;position:relative;width:100%}.Sidebar_sidebarGroupLabel__5VJ-b{align-items:center;border-radius:.375rem;color:var(--sidebar-foreground);display:flex;flex-shrink:0;font-size:.75rem;font-weight:500;height:2rem;opacity:.7;outline:none;padding-left:.5rem;padding-right:.5rem;transition:margin ease-linear .2s,opacity ease-linear .2s}.Sidebar_sidebarGroupLabel__5VJ-b:focus-visible{box-shadow:0 0 0 2px var(--sidebar-ring)}.Sidebar_sidebarGroupLabel__5VJ-b>svg{flex-shrink:0;height:1rem;width:1rem}.Sidebar_sidebarGroupLabel__5VJ-b[data-collapsible=icon]{margin-top:-2rem;opacity:0}.Sidebar_sidebarGroupAction__OhVZq{align-items:center;aspect-ratio:1;border-radius:.375rem;color:var(--sidebar-foreground);display:flex;justify-content:center;outline:none;padding:0;position:absolute;right:.75rem;top:.875rem;transition:transform;width:1.25rem}.Sidebar_sidebarGroupAction__OhVZq:hover{background-color:var(--sidebar-accent);color:var(--sidebar-accent-foreground)}.Sidebar_sidebarGroupAction__OhVZq:focus-visible{box-shadow:0 0 0 2px var(--sidebar-ring)}.Sidebar_sidebarGroupAction__OhVZq>svg{flex-shrink:0;height:1rem;width:1rem}.Sidebar_sidebarGroupAction__OhVZq:after{content:\"\";inset:-.5rem;position:absolute}@media (min-width:768px){.Sidebar_sidebarGroupAction__OhVZq:after{display:none}}.Sidebar_sidebarGroupAction__OhVZq[data-collapsible=icon]{display:none}.Sidebar_sidebarGroupContent__ZqWcj{font-size:.875rem;width:100%}.Sidebar_sidebarMenu__hYXIo{display:flex;flex-direction:column;gap:var(--p-4);list-style:none;min-width:0;padding:0 var(--p-11) var(--p-10) var(--p-8);width:100%}@media (max-width:768px){.Sidebar_sidebarMenu__hYXIo{padding-right:var(--p-8)}}.Sidebar_sidebarMenuItem__CRhM8{cursor:pointer;position:relative}.Sidebar_sidebarMenuBadge__ttvCR{align-items:center;border-radius:.375rem;color:var(--sidebar-foreground);display:flex;font-size:.75rem;font-weight:500;height:1.25rem;justify-content:center;min-width:1.25rem;padding-left:.25rem;padding-right:.25rem;pointer-events:none;position:absolute;right:.25rem;-webkit-user-select:none;-moz-user-select:none;user-select:none}.Sidebar_sidebarMenuBadge__ttvCR[data-size=sm]{top:.25rem}.Sidebar_sidebarMenuBadge__ttvCR[data-size=md]{top:.375rem}.Sidebar_sidebarMenuBadge__ttvCR[data-size=lg]{top:.625rem}.Sidebar_sidebarMenuBadge__ttvCR[data-collapsible=icon]{display:none}.Sidebar_sidebarMenuSkeleton__u2KoI{align-items:center;border-radius:.375rem;display:flex;gap:.5rem;height:2rem;padding-left:.5rem;padding-right:.5rem}.Sidebar_sidebarMenuSkeletonIcon__-1tvv{border-radius:.375rem;height:1rem;width:1rem}.Sidebar_sidebarMenuSkeletonText__dWzWo{flex:1;height:1rem;max-width:var(--skeleton-width)}.Sidebar_sidebarMenuSub__gh8Rn{border-color:var(--sidebar-border);border-left:none;display:flex;flex-direction:column;gap:var(--p-2);list-style:none;margin-left:0;margin-right:0;min-width:0;padding:0;padding-top:var(--p-1);position:relative;transform:translateX(1px)}.Sidebar_sidebarMenuSub__gh8Rn:before{background:var(--sidebar-border);bottom:26px;content:\"\";left:var(--p-5);pointer-events:none;position:absolute;top:0;width:1px}.Sidebar_sidebarMenuSub__gh8Rn[data-collapsible=icon]{display:none}.Sidebar_sidebarMenuSubItem__fTHJa{margin-left:var(--p-6);position:relative}.Sidebar_sidebarMenuSubItem__fTHJa:before{border-bottom:1px solid var(--sidebar-border);border-bottom-left-radius:var(--p-2);border-left:1px solid var(--sidebar-border);bottom:0;content:\"\";height:var(--p-3);left:calc(var(--p-1)*-1);position:absolute;top:var(--p-2);width:var(--p-3)}.Sidebar_sidebarMenuSubItem__fTHJa a:hover{text-decoration:none}.Sidebar_sheetContentSidebar__cM2h2{color:var(--sidebar-foreground);padding:0;width:var(--sidebar-width)}.Sidebar_sheetContentSidebar__cM2h2>button{display:none}@media (max-width:768px){.Sidebar_sheetContentSidebar__cM2h2{z-index:100}}.Sidebar_sheetSidebarInner__U-SMQ{background-color:var(--sidebar);display:flex;flex-direction:column;height:100%;width:100%}.Sidebar_sidebarNone__crRsF{color:var(--sidebar-foreground);display:flex;flex-direction:column;height:100%;width:var(--sidebar-width)}.Sidebar_variant-floating__-qvkJ{padding:.5rem}.Sidebar_variant-floating__-qvkJ[data-collapsible=icon],.Sidebar_variant-inset__oTfrV[data-collapsible=icon]{width:calc(var(--sidebar-width-icon) + 1rem + 2px)}.Sidebar_variant-sidebar__fAe77[data-collapsible=icon]{width:var(--sidebar-width-icon)}.Sidebar_variant-sidebar__fAe77[data-side=left]{border-right:1px solid #e5e7eb}.Sidebar_variant-sidebar__fAe77[data-side=right]{border-left:1px solid #e5e7eb}.Sidebar_sidebarMenuButton__vIEh->span,.Sidebar_sidebarMenuSubButton__c9flh>span{min-width:0;text-transform:capitalize}.Sidebar_sidebarMenuButton__vIEh->span:first-child,.Sidebar_sidebarMenuSubButton__c9flh>span:first-child{flex-grow:1}.Sidebar_sidebarMenuButton__vIEh-{align-items:center;border-radius:var(--p-3);color:var(--sidebar-foreground);cursor:pointer;display:flex;font-size:.875rem;gap:var(--p-2);justify-content:flex-start;outline:none;overflow:hidden;padding:var(--p-6) var(--p-3);text-align:left;text-decoration:none;transition:all;width:100%}.Sidebar_sidebarMenuButton__vIEh-:visited{color:var(--sidebar-foreground)}.Sidebar_sidebarMenuButton__vIEh-:hover{text-decoration:none}.Sidebar_sidebarMenuSubItem__fTHJa:active .Sidebar_sidebarMenuButton__vIEh-,.Sidebar_sidebarMenuSubItem__fTHJa:hover .Sidebar_sidebarMenuButton__vIEh-,.Sidebar_sidebarMenuSubItem__fTHJa[data-state=open] .Sidebar_sidebarMenuButton__vIEh-{background-color:var(--sidebar-accent);color:var(--sidebar-accent-foreground)}.Sidebar_sidebarMenuButton__vIEh-:focus-visible{box-shadow:0 0 0 2px var(--sidebar-ring)}.Sidebar_sidebarMenuButton__vIEh-:disabled,.Sidebar_sidebarMenuButton__vIEh-[aria-disabled=true]{opacity:.5;pointer-events:none}.Sidebar_sidebarMenuButton__vIEh-[data-active=true]{background-color:var(--sidebar-accent);color:var(--sidebar-accent-foreground);font-weight:500}.Sidebar_sidebarMenuButton__vIEh-[data-collapsible=icon]{height:2rem!important;padding:.5rem!important;width:2rem!important}.Sidebar_sidebarMenuButton__vIEh->span{flex-grow:1;line-height:20px;overflow:hidden;white-space:nowrap}.Sidebar_sidebarMenuButton__vIEh->svg{flex-shrink:0;height:var(--p-5);width:var(--p-5)}.Sidebar_sidebarMenuButton__vIEh-.Sidebar_size-sm__7aIbu{font-size:.75rem;height:1.75rem}.Sidebar_sidebarMenuButton__vIEh-.Sidebar_size-md__rcjmO{font-size:.875rem;height:var(--p-12)}.Sidebar_sidebarMenuButton__vIEh-.Sidebar_size-lg__1k76S{font-size:.875rem;height:3rem}.Sidebar_sidebarMenuButton__vIEh-.Sidebar_size-lg__1k76S[data-collapsible=icon]{padding:0!important}.Sidebar_sidebarMenuButton__vIEh-.Sidebar_variant-outline__UmtAz{background-color:var(--background);box-shadow:0 0 0 1px var(--sidebar-border)}.Sidebar_sidebarMenuButton__vIEh-.Sidebar_variant-outline__UmtAz:hover{background-color:var(--sidebar-accent);box-shadow:0 0 0 1px var(--sidebar-accent);color:var(--sidebar-accent-foreground)}.Sidebar_sidebarMenuButtonCta__dQAhv{display:flex;justify-content:flex-start;text-align:left;width:100%}.Sidebar_sidebarMenuButtonCta__dQAhv>svg{flex-shrink:0;height:var(--p-5);width:var(--p-5)}.Sidebar_sidebarMenuAction__mFZa1{align-items:center;aspect-ratio:1;border-radius:.375rem;color:var(--sidebar-foreground);cursor:pointer;display:flex;justify-content:center;opacity:0;outline:none;padding:0;position:absolute;right:var(--p-2);top:var(--p-2);transition:transform;width:1.25rem}.Sidebar_sidebarMenuAction__mFZa1:before{background-image:linear-gradient(to left,var(--sidebar-accent) 70%,transparent 100%);content:\"\";height:100%;pointer-events:none;position:absolute;right:0;transition:opacity .2s ease-in-out;width:calc(100% + var(--p-4))}.Sidebar_sidebarMenuSubItem__fTHJa:hover .Sidebar_sidebarMenuAction__mFZa1{opacity:1}.Sidebar_sidebarMenuAction__mFZa1:focus-visible{box-shadow:0 0 0 2px var(--sidebar-ring)}.Sidebar_sidebarMenuAction__mFZa1>svg{flex-shrink:0;height:1rem;opacity:.5;pointer-events:none;transition:opacity .2s ease-in-out;width:1rem;z-index:1}.Sidebar_sidebarMenuAction__mFZa1:hover>svg{opacity:1}.Sidebar_sidebarMenuAction__mFZa1:after{content:\"\";inset:-.5rem;position:absolute}@media (min-width:768px){.Sidebar_sidebarMenuAction__mFZa1:after{display:none}}.Sidebar_sidebarMenuAction__mFZa1[data-size=sm]{top:.25rem}.Sidebar_sidebarMenuAction__mFZa1[data-size=md]{top:.375rem}.Sidebar_sidebarMenuAction__mFZa1[data-size=lg]{top:.625rem}.Sidebar_sidebarMenuAction__mFZa1[data-collapsible=icon]{display:none}.Sidebar_sidebarMenuAction__mFZa1.Sidebar_showOnHover__itXsA[data-active=true]{color:var(--sidebar-accent-foreground)}.Sidebar_sidebarMenuAction__mFZa1.Sidebar_showOnHover__itXsA[data-state=open]{opacity:1}@media (min-width:768px){.Sidebar_sidebarMenuAction__mFZa1.Sidebar_showOnHover__itXsA{opacity:0}.Sidebar_sidebarMenuAction__mFZa1.Sidebar_showOnHover__itXsA:focus-within,.Sidebar_sidebarMenuAction__mFZa1.Sidebar_showOnHover__itXsA:hover{opacity:1}}.Sidebar_sidebarMenuSubButton__c9flh{align-items:center;border-radius:var(--p-3);color:var(--sidebar-foreground);cursor:pointer;display:flex;gap:var(--p-1);height:var(--p-9);margin-left:var(--p-3);min-width:0;outline:none;overflow:hidden;padding:var(--p-1) var(--p-2);text-decoration:none;transform:translateX(-1px)}.Sidebar_sidebarMenuSubButton__c9flh:visited{color:var(--sidebar-foreground)}.Sidebar_sidebarMenuSubButton__c9flh:hover{text-decoration:none}.Sidebar_sidebarMenuSubItem__fTHJa:active .Sidebar_sidebarMenuSubButton__c9flh,.Sidebar_sidebarMenuSubItem__fTHJa:hover .Sidebar_sidebarMenuSubButton__c9flh{background-color:var(--sidebar-accent);color:var(--sidebar-accent-foreground)}.Sidebar_sidebarMenuSubButton__c9flh:focus-visible{box-shadow:0 0 0 2px var(--sidebar-ring)}.Sidebar_sidebarMenuSubButton__c9flh:disabled,.Sidebar_sidebarMenuSubButton__c9flh[aria-disabled=true]{opacity:.5;pointer-events:none}.Sidebar_sidebarMenuSubButton__c9flh[data-active=true]{background-color:var(--sidebar-accent);color:var(--sidebar-accent-foreground)}.Sidebar_sidebarMenuSubButton__c9flh[data-active=true]:visited{color:var(--sidebar-accent-foreground)}.Sidebar_sidebarMenuSubButton__c9flh[data-collapsible=icon]{display:none}.Sidebar_sidebarMenuSubButton__c9flh>span:first-child{overflow:hidden;white-space:nowrap}.Sidebar_sidebarMenuSubButton__c9flh>svg{color:var(--sidebar-accent-foreground);flex-shrink:0;height:1rem;width:1rem}.Sidebar_sidebarMenuSubButton__c9flh.Sidebar_size-sm__7aIbu{font-size:.75rem}.Sidebar_sidebarMenuSubButton__c9flh.Sidebar_size-md__rcjmO{font-size:.875rem}.Sidebar_sidebarMenuSubButton__c9flh.Sidebar_size-lg__1k76S{font-size:1rem}::view-transition-old(sidebar-container),::view-transition-old(sidebar-gap){animation-duration:.2s;animation-name:Sidebar_sidebarVtOld__hlKqn;animation-timing-function:ease-out;transform:translateZ(0)}::view-transition-new(sidebar-container),::view-transition-new(sidebar-gap){animation-duration:.2s;animation-name:Sidebar_sidebarVtNew__FFhYU;animation-timing-function:ease-out;transform:translateZ(0)}@keyframes Sidebar_sidebarVtOld__hlKqn{0%{opacity:1}to{opacity:0}}@keyframes Sidebar_sidebarVtNew__FFhYU{0%{opacity:0}to{opacity:1}}";
4
- var SidebarStem = {"sidebarWrapper":"Sidebar_sidebarWrapper__DGm4P","sidebarMainShell":"Sidebar_sidebarMainShell__pSWDC","chatPanelMount":"Sidebar_chatPanelMount__1Zctx","sidebar":"Sidebar_sidebar__0vqNZ","sidebarTrigger":"Sidebar_sidebarTrigger__ipx2C","sidebarRail":"Sidebar_sidebarRail__uvSpl","sidebarResizeHandle":"Sidebar_sidebarResizeHandle__kuD6t","fullHeightResizer":"Sidebar_fullHeightResizer__jZXnw","sidebarInput":"Sidebar_sidebarInput__ujQLX","sidebarHeader":"Sidebar_sidebarHeader__X33ii","sidebarFooter":"Sidebar_sidebarFooter__V3O-l","sidebarSeparator":"Sidebar_sidebarSeparator__oUkYG","sidebarContent":"Sidebar_sidebarContent__Ywe1o","sidebarGroup":"Sidebar_sidebarGroup__7Mhg2","sidebarGroupLabel":"Sidebar_sidebarGroupLabel__5VJ-b","sidebarGroupAction":"Sidebar_sidebarGroupAction__OhVZq","sidebarGroupContent":"Sidebar_sidebarGroupContent__ZqWcj","sidebarMenu":"Sidebar_sidebarMenu__hYXIo","sidebarMenuItem":"Sidebar_sidebarMenuItem__CRhM8","sidebarMenuBadge":"Sidebar_sidebarMenuBadge__ttvCR","sidebarMenuSkeleton":"Sidebar_sidebarMenuSkeleton__u2KoI","sidebarMenuSkeletonIcon":"Sidebar_sidebarMenuSkeletonIcon__-1tvv","sidebarMenuSkeletonText":"Sidebar_sidebarMenuSkeletonText__dWzWo","sidebarMenuSub":"Sidebar_sidebarMenuSub__gh8Rn","sidebarMenuSubItem":"Sidebar_sidebarMenuSubItem__fTHJa","sheetContentSidebar":"Sidebar_sheetContentSidebar__cM2h2","sheetSidebarInner":"Sidebar_sheetSidebarInner__U-SMQ","sidebarNone":"Sidebar_sidebarNone__crRsF","variant-floating":"Sidebar_variant-floating__-qvkJ","variant-inset":"Sidebar_variant-inset__oTfrV","variant-sidebar":"Sidebar_variant-sidebar__fAe77","sidebarMenuButton":"Sidebar_sidebarMenuButton__vIEh-","sidebarMenuSubButton":"Sidebar_sidebarMenuSubButton__c9flh","size-sm":"Sidebar_size-sm__7aIbu","size-md":"Sidebar_size-md__rcjmO","size-lg":"Sidebar_size-lg__1k76S","variant-outline":"Sidebar_variant-outline__UmtAz","sidebarMenuButtonCta":"Sidebar_sidebarMenuButtonCta__dQAhv","sidebarMenuAction":"Sidebar_sidebarMenuAction__mFZa1","showOnHover":"Sidebar_showOnHover__itXsA","sidebarVtOld":"Sidebar_sidebarVtOld__hlKqn","sidebarVtNew":"Sidebar_sidebarVtNew__FFhYU"};
3
+ var css_248z = "@media (max-width:768px){:root{--page-x-padding:var(--p-6);--page-y-padding:var(--p-6)}}.Sidebar_sidebarWrapper__DGm4P{align-items:stretch;display:flex;flex-direction:row;--welcome-alert-height:44px;height:calc(100% - 44px);height:calc(100% - var(--welcome-alert-height));min-height:0;width:100%}.Sidebar_sidebarWrapper__DGm4P #page-sidebar-actions{min-height:100%}@media (max-width:768px){.Sidebar_sidebarWrapper__DGm4P{flex-direction:column;height:100dvh;max-height:100dvh}}.Sidebar_sidebarMainShell__pSWDC{display:flex;flex:1;flex-direction:column;min-height:0;min-width:0}.Sidebar_chatPanelMount__1Zctx{background:var(--background);border-left:1px solid var(--border);flex:0 0 0px;flex:0 0 var(--chat-panel-width,0px);min-height:0;min-width:0;overflow:hidden;width:0;width:var(--chat-panel-width,0)}@media (max-width:768px){.Sidebar_chatPanelMount__1Zctx{border-left:none;border-top:1px solid var(--border);flex:0 0 0px;flex:0 0 var(--chat-panel-height,0px);height:0;height:var(--chat-panel-height,0);transition:flex-basis .2s ease,height .2s ease;width:100%}}.Sidebar_sidebar__0vqNZ{height:0;position:fixed;--top-offset:-10px;--gap-top:calc(var(--header-height) + var(--top-offset));align-self:flex-start;color:var(--sidebar-foreground);display:none;flex-direction:column;top:var(--gap-top);width:var(--sidebar-width)}@media (min-width:768px){.Sidebar_sidebar__0vqNZ[data-state=expanded]{display:flex;height:calc(100vh - var(--gap-top));min-height:0}}.Sidebar_sidebar__0vqNZ[data-collapsible=offcanvas]{overflow:hidden;padding:0;width:0}.Sidebar_sidebarTrigger__ipx2C{cursor:pointer;height:var(--p-5);width:var(--p-5)}.Sidebar_sidebarTrigger__ipx2C svg{height:20px;width:20px}.Sidebar_sidebarRail__uvSpl{position:absolute;inset-y:0;display:hidden;transition:all ease-out;width:1rem;z-index:20}.Sidebar_sidebarRail__uvSpl:hover:after{background-color:var(--sidebar-border)}.Sidebar_sidebarRail__uvSpl[data-side=left]{right:-1rem}.Sidebar_sidebarRail__uvSpl[data-side=right]{left:0}.Sidebar_sidebarRail__uvSpl:after{content:\"\";position:absolute;inset-y:0;left:50%;width:2px}@media (min-width:640px){.Sidebar_sidebarRail__uvSpl{display:flex}}.Sidebar_sidebarRail__uvSpl[data-side=left]{cursor:w-resize}.Sidebar_sidebarRail__uvSpl[data-side=left][data-state=collapsed],.Sidebar_sidebarRail__uvSpl[data-side=right]{cursor:e-resize}.Sidebar_sidebarRail__uvSpl[data-side=right][data-state=collapsed]{cursor:w-resize}.Sidebar_sidebarRail__uvSpl[data-collapsible=offcanvas]{transform:translateX(0)}.Sidebar_sidebarRail__uvSpl[data-collapsible=offcanvas]:hover{background-color:var(--sidebar)}.Sidebar_sidebarRail__uvSpl[data-collapsible=offcanvas]:after{left:100%}.Sidebar_sidebarRail__uvSpl[data-side=left][data-collapsible=offcanvas]{right:-.5rem}.Sidebar_sidebarRail__uvSpl[data-side=right][data-collapsible=offcanvas]{left:-.5rem}.Sidebar_sidebarResizeHandle__kuD6t{background-color:transparent;background-color:var(--page-color);border-radius:2.5px;height:calc(100vh + 200px);opacity:0;position:absolute;top:-200px;touch-action:none;transition:opacity .15s ease-out;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:5px;z-index:30}.Sidebar_sidebarResizeHandle__kuD6t:before{content:\"\";cursor:col-resize;height:100%;position:absolute;right:0;width:30px}.Sidebar_sidebarResizeHandle__kuD6t[data-side=left]{right:2px}.Sidebar_sidebarResizeHandle__kuD6t[data-side=right]{left:0}.Sidebar_sidebarResizeHandle__kuD6t:hover{opacity:1}.Sidebar_sidebarResizeHandle__kuD6t:active{opacity:0}.Sidebar_fullHeightResizer__jZXnw .Sidebar_sidebarResizeHandle__kuD6t{height:calc(100vh - var(--gap-top)*-1);top:-80px}.Sidebar_sidebarInput__ujQLX{background-color:var(--background);box-shadow:none;height:2rem;width:100%}.Sidebar_sidebarFooter__V3O-l,.Sidebar_sidebarHeader__X33ii{display:flex;flex-direction:column;gap:0;padding:0}.Sidebar_sidebarSeparator__oUkYG{background-color:var(--sidebar-border);margin-left:0;margin-right:0;width:auto}.Sidebar_sidebarContent__Ywe1o{display:flex;flex:1;flex-direction:column;gap:var(--p-16);height:100vh;max-height:100vh;min-height:0;overflow:auto;position:absolute;width:100%}@media (min-width:768px){.Sidebar_sidebarContent__Ywe1o{height:calc(100vh - var(--gap-top))}}.Sidebar_sidebarContent__Ywe1o[data-collapsible=icon]{overflow:hidden}.Sidebar_sidebarGroup__7Mhg2{display:flex;flex-direction:column;min-width:0;padding:40px 0 0;position:relative;width:100%}.Sidebar_sidebarGroupLabel__5VJ-b{align-items:center;border-radius:.375rem;color:var(--sidebar-foreground);display:flex;flex-shrink:0;font-size:.75rem;font-weight:500;height:2rem;opacity:.7;outline:none;padding-left:.5rem;padding-right:.5rem;transition:margin ease-linear .2s,opacity ease-linear .2s}.Sidebar_sidebarGroupLabel__5VJ-b:focus-visible{box-shadow:0 0 0 2px var(--sidebar-ring)}.Sidebar_sidebarGroupLabel__5VJ-b>svg{flex-shrink:0;height:1rem;width:1rem}.Sidebar_sidebarGroupLabel__5VJ-b[data-collapsible=icon]{margin-top:-2rem;opacity:0}.Sidebar_sidebarGroupAction__OhVZq{align-items:center;aspect-ratio:1;border-radius:.375rem;color:var(--sidebar-foreground);display:flex;justify-content:center;outline:none;padding:0;position:absolute;right:.75rem;top:.875rem;transition:transform;width:1.25rem}.Sidebar_sidebarGroupAction__OhVZq:hover{background-color:var(--sidebar-accent);color:var(--sidebar-accent-foreground)}.Sidebar_sidebarGroupAction__OhVZq:focus-visible{box-shadow:0 0 0 2px var(--sidebar-ring)}.Sidebar_sidebarGroupAction__OhVZq>svg{flex-shrink:0;height:1rem;width:1rem}.Sidebar_sidebarGroupAction__OhVZq:after{content:\"\";inset:-.5rem;position:absolute}@media (min-width:768px){.Sidebar_sidebarGroupAction__OhVZq:after{display:none}}.Sidebar_sidebarGroupAction__OhVZq[data-collapsible=icon]{display:none}.Sidebar_sidebarMenu__hYXIo{display:flex;flex-direction:column;gap:var(--p-4);list-style:none;min-width:0;padding:0 var(--p-11) var(--p-10) var(--p-8);width:100%}@media (max-width:768px){.Sidebar_sidebarMenu__hYXIo{padding-right:var(--p-8)}}.Sidebar_sidebarMenuItem__CRhM8{cursor:pointer;position:relative}.Sidebar_sidebarMenuBadge__ttvCR{align-items:center;border-radius:.375rem;color:var(--sidebar-foreground);display:flex;font-size:.75rem;font-weight:500;height:1.25rem;justify-content:center;min-width:1.25rem;padding-left:.25rem;padding-right:.25rem;pointer-events:none;position:absolute;right:.25rem;-webkit-user-select:none;-moz-user-select:none;user-select:none}.Sidebar_sidebarMenuBadge__ttvCR[data-size=sm]{top:.25rem}.Sidebar_sidebarMenuBadge__ttvCR[data-size=md]{top:.375rem}.Sidebar_sidebarMenuBadge__ttvCR[data-size=lg]{top:.625rem}.Sidebar_sidebarMenuBadge__ttvCR[data-collapsible=icon]{display:none}.Sidebar_sidebarMenuSkeleton__u2KoI{align-items:center;border-radius:.375rem;display:flex;gap:.5rem;height:2rem;padding-left:.5rem;padding-right:.5rem}.Sidebar_sidebarMenuSkeletonIcon__-1tvv{border-radius:.375rem;height:1rem;width:1rem}.Sidebar_sidebarMenuSkeletonText__dWzWo{flex:1;height:1rem;max-width:var(--skeleton-width)}.Sidebar_sidebarMenuSub__gh8Rn{border-color:var(--sidebar-border);border-left:none;display:flex;flex-direction:column;gap:var(--p-2);list-style:none;margin-left:0;margin-right:0;min-width:0;padding:0;padding-top:var(--p-1);position:relative;transform:translateX(1px)}.Sidebar_sidebarMenuSub__gh8Rn:before{background:var(--sidebar-border);bottom:26px;content:\"\";left:var(--p-5);pointer-events:none;position:absolute;top:0;width:1px}.Sidebar_sidebarMenuSub__gh8Rn[data-collapsible=icon]{display:none}.Sidebar_sidebarMenuSubItem__fTHJa{margin-left:var(--p-6);position:relative}.Sidebar_sidebarMenuSubItem__fTHJa:before{border-bottom:1px solid var(--sidebar-border);border-bottom-left-radius:var(--p-2);border-left:1px solid var(--sidebar-border);bottom:0;content:\"\";height:var(--p-3);left:calc(var(--p-1)*-1);position:absolute;top:var(--p-2);width:var(--p-3)}.Sidebar_sidebarMenuSubItem__fTHJa a:hover{text-decoration:none}.Sidebar_sheetContentSidebar__cM2h2{color:var(--sidebar-foreground);padding:0;width:var(--sidebar-width)}.Sidebar_sheetContentSidebar__cM2h2>button{display:none}@media (max-width:768px){.Sidebar_sheetContentSidebar__cM2h2{z-index:100}}.Sidebar_sheetSidebarInner__U-SMQ{background-color:var(--sidebar);display:flex;flex-direction:column;height:100%;width:100%}.Sidebar_sidebarNone__crRsF{color:var(--sidebar-foreground);display:flex;flex-direction:column;height:100%;width:var(--sidebar-width)}.Sidebar_variant-floating__-qvkJ{padding:.5rem}.Sidebar_variant-floating__-qvkJ[data-collapsible=icon],.Sidebar_variant-inset__oTfrV[data-collapsible=icon]{width:calc(var(--sidebar-width-icon) + 1rem + 2px)}.Sidebar_variant-sidebar__fAe77[data-collapsible=icon]{width:var(--sidebar-width-icon)}.Sidebar_variant-sidebar__fAe77[data-side=left]{border-right:1px solid #e5e7eb}.Sidebar_variant-sidebar__fAe77[data-side=right]{border-left:1px solid #e5e7eb}.Sidebar_sidebarMenuButton__vIEh->span,.Sidebar_sidebarMenuSubButton__c9flh>span{min-width:0;text-transform:capitalize}.Sidebar_sidebarMenuButton__vIEh->span:first-child,.Sidebar_sidebarMenuSubButton__c9flh>span:first-child{flex-grow:1}.Sidebar_sidebarMenuButton__vIEh-{align-items:center;border-radius:var(--p-3);color:var(--sidebar-foreground);cursor:pointer;display:flex;font-size:.875rem;gap:var(--p-2);justify-content:flex-start;outline:none;overflow:hidden;padding:var(--p-6) var(--p-3);text-align:left;text-decoration:none;transition:all;width:100%}.Sidebar_sidebarMenuButton__vIEh-:visited{color:var(--sidebar-foreground)}.Sidebar_sidebarMenuButton__vIEh-:hover{text-decoration:none}.Sidebar_sidebarMenuSubItem__fTHJa:active .Sidebar_sidebarMenuButton__vIEh-,.Sidebar_sidebarMenuSubItem__fTHJa:hover .Sidebar_sidebarMenuButton__vIEh-,.Sidebar_sidebarMenuSubItem__fTHJa[data-state=open] .Sidebar_sidebarMenuButton__vIEh-{background-color:var(--sidebar-accent);color:var(--sidebar-accent-foreground)}.Sidebar_sidebarMenuButton__vIEh-:focus-visible{box-shadow:0 0 0 2px var(--sidebar-ring)}.Sidebar_sidebarMenuButton__vIEh-:disabled,.Sidebar_sidebarMenuButton__vIEh-[aria-disabled=true]{opacity:.5;pointer-events:none}.Sidebar_sidebarMenuButton__vIEh-[data-active=true]{background-color:var(--sidebar-accent);color:var(--sidebar-accent-foreground);font-weight:500}.Sidebar_sidebarMenuButton__vIEh-[data-collapsible=icon]{height:2rem!important;padding:.5rem!important;width:2rem!important}.Sidebar_sidebarMenuButton__vIEh->span{flex-grow:1;line-height:20px;overflow:hidden;white-space:nowrap}.Sidebar_sidebarMenuButton__vIEh->svg{flex-shrink:0;height:var(--p-5);width:var(--p-5)}.Sidebar_sidebarMenuButton__vIEh-.Sidebar_size-sm__7aIbu{font-size:.75rem;height:1.75rem}.Sidebar_sidebarMenuButton__vIEh-.Sidebar_size-md__rcjmO{font-size:.875rem;height:var(--p-12)}.Sidebar_sidebarMenuButton__vIEh-.Sidebar_size-lg__1k76S{font-size:.875rem;height:3rem}.Sidebar_sidebarMenuButton__vIEh-.Sidebar_size-lg__1k76S[data-collapsible=icon]{padding:0!important}.Sidebar_sidebarMenuButton__vIEh-.Sidebar_variant-outline__UmtAz{background-color:var(--background);box-shadow:0 0 0 1px var(--sidebar-border)}.Sidebar_sidebarMenuButton__vIEh-.Sidebar_variant-outline__UmtAz:hover{background-color:var(--sidebar-accent);box-shadow:0 0 0 1px var(--sidebar-accent);color:var(--sidebar-accent-foreground)}.Sidebar_sidebarMenuButtonCta__dQAhv{display:flex;justify-content:flex-start;text-align:left;width:100%}.Sidebar_sidebarMenuButtonCta__dQAhv>svg{flex-shrink:0;height:var(--p-5);width:var(--p-5)}.Sidebar_sidebarMenuAction__mFZa1{align-items:center;aspect-ratio:1;border-radius:.375rem;color:var(--sidebar-foreground);cursor:pointer;display:flex;justify-content:center;opacity:0;outline:none;padding:0;position:absolute;right:var(--p-2);top:var(--p-2);transition:transform;width:1.25rem}.Sidebar_sidebarMenuAction__mFZa1:before{background-image:linear-gradient(to left,var(--sidebar-accent) 70%,transparent 100%);content:\"\";height:100%;pointer-events:none;position:absolute;right:0;transition:opacity .2s ease-in-out;width:calc(100% + var(--p-4))}.Sidebar_sidebarMenuSubItem__fTHJa:hover .Sidebar_sidebarMenuAction__mFZa1{opacity:1}.Sidebar_sidebarMenuAction__mFZa1:focus-visible{box-shadow:0 0 0 2px var(--sidebar-ring)}.Sidebar_sidebarMenuAction__mFZa1>svg{flex-shrink:0;height:1rem;opacity:.5;pointer-events:none;transition:opacity .2s ease-in-out;width:1rem;z-index:1}.Sidebar_sidebarMenuAction__mFZa1:hover>svg{opacity:1}.Sidebar_sidebarMenuAction__mFZa1:after{content:\"\";inset:-.5rem;position:absolute}@media (min-width:768px){.Sidebar_sidebarMenuAction__mFZa1:after{display:none}}.Sidebar_sidebarMenuAction__mFZa1[data-size=sm]{top:.25rem}.Sidebar_sidebarMenuAction__mFZa1[data-size=md]{top:.375rem}.Sidebar_sidebarMenuAction__mFZa1[data-size=lg]{top:.625rem}.Sidebar_sidebarMenuAction__mFZa1[data-collapsible=icon]{display:none}.Sidebar_sidebarMenuAction__mFZa1.Sidebar_showOnHover__itXsA[data-active=true]{color:var(--sidebar-accent-foreground)}.Sidebar_sidebarMenuAction__mFZa1.Sidebar_showOnHover__itXsA[data-state=open]{opacity:1}@media (min-width:768px){.Sidebar_sidebarMenuAction__mFZa1.Sidebar_showOnHover__itXsA{opacity:0}.Sidebar_sidebarMenuAction__mFZa1.Sidebar_showOnHover__itXsA:focus-within,.Sidebar_sidebarMenuAction__mFZa1.Sidebar_showOnHover__itXsA:hover{opacity:1}}.Sidebar_sidebarMenuSubButton__c9flh{align-items:center;border-radius:var(--p-3);color:var(--sidebar-foreground);cursor:pointer;display:flex;gap:var(--p-1);height:var(--p-9);margin-left:var(--p-3);min-width:0;outline:none;overflow:hidden;padding:var(--p-1) var(--p-2);text-decoration:none;transform:translateX(-1px)}.Sidebar_sidebarMenuSubButton__c9flh:visited{color:var(--sidebar-foreground)}.Sidebar_sidebarMenuSubButton__c9flh:hover{text-decoration:none}.Sidebar_sidebarMenuSubItem__fTHJa:active .Sidebar_sidebarMenuSubButton__c9flh,.Sidebar_sidebarMenuSubItem__fTHJa:hover .Sidebar_sidebarMenuSubButton__c9flh{background-color:var(--sidebar-accent);color:var(--sidebar-accent-foreground)}.Sidebar_sidebarMenuSubButton__c9flh:focus-visible{box-shadow:0 0 0 2px var(--sidebar-ring)}.Sidebar_sidebarMenuSubButton__c9flh:disabled,.Sidebar_sidebarMenuSubButton__c9flh[aria-disabled=true]{opacity:.5;pointer-events:none}.Sidebar_sidebarMenuSubButton__c9flh[data-active=true]{background-color:var(--sidebar-accent);color:var(--sidebar-accent-foreground)}.Sidebar_sidebarMenuSubButton__c9flh[data-active=true]:visited{color:var(--sidebar-accent-foreground)}.Sidebar_sidebarMenuSubButton__c9flh[data-collapsible=icon]{display:none}.Sidebar_sidebarMenuSubButton__c9flh>span:first-child{overflow:hidden;white-space:nowrap}.Sidebar_sidebarMenuSubButton__c9flh>svg{color:var(--sidebar-accent-foreground);flex-shrink:0;height:1rem;width:1rem}.Sidebar_sidebarMenuSubButton__c9flh.Sidebar_size-sm__7aIbu{font-size:.75rem}.Sidebar_sidebarMenuSubButton__c9flh.Sidebar_size-md__rcjmO{font-size:.875rem}.Sidebar_sidebarMenuSubButton__c9flh.Sidebar_size-lg__1k76S{font-size:1rem}::view-transition-old(sidebar-container),::view-transition-old(sidebar-gap){animation-duration:.2s;animation-name:Sidebar_sidebarVtOld__hlKqn;animation-timing-function:ease-out;transform:translateZ(0)}::view-transition-new(sidebar-container),::view-transition-new(sidebar-gap){animation-duration:.2s;animation-name:Sidebar_sidebarVtNew__FFhYU;animation-timing-function:ease-out;transform:translateZ(0)}@keyframes Sidebar_sidebarVtOld__hlKqn{0%{opacity:1}to{opacity:0}}@keyframes Sidebar_sidebarVtNew__FFhYU{0%{opacity:0}to{opacity:1}}";
4
+ var SidebarStem = {"sidebarWrapper":"Sidebar_sidebarWrapper__DGm4P","sidebarMainShell":"Sidebar_sidebarMainShell__pSWDC","chatPanelMount":"Sidebar_chatPanelMount__1Zctx","sidebar":"Sidebar_sidebar__0vqNZ","sidebarTrigger":"Sidebar_sidebarTrigger__ipx2C","sidebarRail":"Sidebar_sidebarRail__uvSpl","sidebarResizeHandle":"Sidebar_sidebarResizeHandle__kuD6t","fullHeightResizer":"Sidebar_fullHeightResizer__jZXnw","sidebarInput":"Sidebar_sidebarInput__ujQLX","sidebarHeader":"Sidebar_sidebarHeader__X33ii","sidebarFooter":"Sidebar_sidebarFooter__V3O-l","sidebarSeparator":"Sidebar_sidebarSeparator__oUkYG","sidebarContent":"Sidebar_sidebarContent__Ywe1o","sidebarGroup":"Sidebar_sidebarGroup__7Mhg2","sidebarGroupLabel":"Sidebar_sidebarGroupLabel__5VJ-b","sidebarGroupAction":"Sidebar_sidebarGroupAction__OhVZq","sidebarMenu":"Sidebar_sidebarMenu__hYXIo","sidebarMenuItem":"Sidebar_sidebarMenuItem__CRhM8","sidebarMenuBadge":"Sidebar_sidebarMenuBadge__ttvCR","sidebarMenuSkeleton":"Sidebar_sidebarMenuSkeleton__u2KoI","sidebarMenuSkeletonIcon":"Sidebar_sidebarMenuSkeletonIcon__-1tvv","sidebarMenuSkeletonText":"Sidebar_sidebarMenuSkeletonText__dWzWo","sidebarMenuSub":"Sidebar_sidebarMenuSub__gh8Rn","sidebarMenuSubItem":"Sidebar_sidebarMenuSubItem__fTHJa","sheetContentSidebar":"Sidebar_sheetContentSidebar__cM2h2","sheetSidebarInner":"Sidebar_sheetSidebarInner__U-SMQ","sidebarNone":"Sidebar_sidebarNone__crRsF","variant-floating":"Sidebar_variant-floating__-qvkJ","variant-inset":"Sidebar_variant-inset__oTfrV","variant-sidebar":"Sidebar_variant-sidebar__fAe77","sidebarMenuButton":"Sidebar_sidebarMenuButton__vIEh-","sidebarMenuSubButton":"Sidebar_sidebarMenuSubButton__c9flh","size-sm":"Sidebar_size-sm__7aIbu","size-md":"Sidebar_size-md__rcjmO","size-lg":"Sidebar_size-lg__1k76S","variant-outline":"Sidebar_variant-outline__UmtAz","sidebarMenuButtonCta":"Sidebar_sidebarMenuButtonCta__dQAhv","sidebarMenuAction":"Sidebar_sidebarMenuAction__mFZa1","showOnHover":"Sidebar_showOnHover__itXsA","sidebarVtOld":"Sidebar_sidebarVtOld__hlKqn","sidebarVtNew":"Sidebar_sidebarVtNew__FFhYU"};
5
5
  styleInject(css_248z);
6
6
 
7
7
  export { SidebarStem as default };
package/dist/esm/index.js CHANGED
@@ -1,6 +1,7 @@
1
- export { MINIAPP_CHANNEL, MINIAPP_VERSION, applyThemeToDocument, buildDataRequestMessage, buildReadyMessage, isTrustedMiniAppParentMessage, parseDataResponseMessage, parseThemeSyncMessage, resolveParentOriginFromReferrer } from './mini-app/miniAppProtocol.js';
1
+ export { MINIAPP_CHANNEL, MINIAPP_VERSION, applyThemeToDocument, buildChatSendMessage, buildDataRequestMessage, buildReadyMessage, isTrustedMiniAppParentMessage, parseChatSendResultMessage, parseDataResponseMessage, parseThemeSyncMessage, resolveParentOriginFromReferrer } from './mini-app/miniAppProtocol.js';
2
2
  export { createMiniAppDataClient } from './mini-app/miniAppDataClient.js';
3
3
  export { getDefaultMiniAppThemeConfig } from './mini-app/miniAppThemeConfig.js';
4
+ export { sendChatMessage } from './mini-app/miniAppChatBridge.js';
4
5
  export { MiniAppRoot, useMiniAppShellTheme } from './mini-app/MiniAppRoot.js';
5
6
  export { ChatContext, ChatProvider, useChat, useChats, useChatsForDataset, useChatsForScopeId, useCurrentChat } from './contexts/chat-context.js';
6
7
  export { AnalysesSelector } from './components/ui/AnalysesSelector/AnalysesSelector.js';
@@ -61,7 +62,7 @@ export { Renamer } from './components/ui/Renamer/Renamer.js';
61
62
  export { Select, SelectContent, SelectGroup, SelectItem, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue } from './components/ui/Select/Select.js';
62
63
  export { Separator } from './components/ui/Separator/Separator.js';
63
64
  export { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger } from './components/ui/Sheet/Sheet.js';
64
- export { PanelResizeHandle, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarResizeHandle, SidebarSeparator, SidebarTrigger, useSidebar } from './components/ui/Sidebar/Sidebar.js';
65
+ export { PanelResizeHandle, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarResizeHandle, SidebarSeparator, SidebarTrigger, useSidebar } from './components/ui/Sidebar/Sidebar.js';
65
66
  export { Skeleton } from './components/ui/Skeleton/Skeleton.js';
66
67
  export { Slider } from './components/ui/Slider/Slider.js';
67
68
  export { SmartTextTruncate } from './components/ui/SmartTextTruncate/SmartTextTruncate.js';
@@ -0,0 +1,45 @@
1
+ import { resolveParentOriginFromReferrer, buildChatSendMessage, isTrustedMiniAppParentMessage, parseChatSendResultMessage } from './miniAppProtocol.js';
2
+
3
+ const DEFAULT_TIMEOUT_MS = 60_000;
4
+ /**
5
+ * Ask the Sybilion host to send a chat message with its auth token.
6
+ * Does not update host ChatSheet state — same session as `chatId` on the agent only.
7
+ */
8
+ async function sendChatMessage(chatId, message) {
9
+ if (typeof window === 'undefined' || window.parent === window) {
10
+ throw new Error('sendChatMessage requires an embedded mini-app (iframe)');
11
+ }
12
+ const requestId = crypto.randomUUID();
13
+ const target = resolveParentOriginFromReferrer();
14
+ const payload = { requestId, chatId, message };
15
+ const msg = buildChatSendMessage(payload);
16
+ return new Promise((resolve, reject) => {
17
+ const onMessage = (event) => {
18
+ if (!isTrustedMiniAppParentMessage(event))
19
+ return;
20
+ const parsed = parseChatSendResultMessage(event.data);
21
+ if (!parsed || parsed.requestId !== requestId)
22
+ return;
23
+ window.removeEventListener('message', onMessage);
24
+ clearTimeout(timer);
25
+ if (parsed.ok === true) {
26
+ resolve(parsed.result);
27
+ return;
28
+ }
29
+ reject(new Error(parsed.error));
30
+ };
31
+ window.addEventListener('message', onMessage);
32
+ const timer = setTimeout(() => {
33
+ window.removeEventListener('message', onMessage);
34
+ reject(new Error('Mini-app chat request timed out'));
35
+ }, DEFAULT_TIMEOUT_MS);
36
+ if (target) {
37
+ window.parent.postMessage(msg, target);
38
+ }
39
+ else {
40
+ window.parent.postMessage(msg, '*');
41
+ }
42
+ });
43
+ }
44
+
45
+ export { sendChatMessage };
@@ -1,7 +1,3 @@
1
- /**
2
- * postMessage protocol for Sybilion workspace mini-apps (iframe child).
3
- * Keep in sync with sybilion-client `src/workspace/miniAppBridge.ts` (channel, version, payloads).
4
- */
5
1
  const MINIAPP_CHANNEL = 'sybilion.miniapp';
6
2
  const MINIAPP_VERSION = 1;
7
3
  function isRecord(v) {
@@ -70,6 +66,14 @@ function buildDataRequestMessage(payload) {
70
66
  payload,
71
67
  };
72
68
  }
69
+ function buildChatSendMessage(payload) {
70
+ return {
71
+ channel: MINIAPP_CHANNEL,
72
+ version: MINIAPP_VERSION,
73
+ type: 'CHAT_SEND',
74
+ payload,
75
+ };
76
+ }
73
77
  /** Parse parent → child DATA_RESPONSE. */
74
78
  function parseDataResponseMessage(data) {
75
79
  if (!isRecord(data))
@@ -102,5 +106,48 @@ function parseDataResponseMessage(data) {
102
106
  }
103
107
  return base;
104
108
  }
109
+ /** Parse parent → child CHAT_SEND_RESULT (shell uses `buildChatSendResultMessage`). */
110
+ function parseChatSendResultMessage(data) {
111
+ if (!isRecord(data))
112
+ return null;
113
+ if (data.channel !== MINIAPP_CHANNEL)
114
+ return null;
115
+ if (data.version !== MINIAPP_VERSION)
116
+ return null;
117
+ if (data.type !== 'CHAT_SEND_RESULT')
118
+ return null;
119
+ const payload = data.payload;
120
+ if (!isRecord(payload))
121
+ return null;
122
+ const requestId = payload.requestId;
123
+ if (typeof requestId !== 'string' || requestId.length === 0)
124
+ return null;
125
+ if (payload.ok === true) {
126
+ const result = payload.result;
127
+ if (!isRecord(result))
128
+ return null;
129
+ const responseText = result.response;
130
+ if (typeof responseText !== 'string')
131
+ return null;
132
+ const sidRaw = result.session_id;
133
+ if (sidRaw !== undefined && sidRaw !== null && typeof sidRaw !== 'string')
134
+ return null;
135
+ const session_id = typeof sidRaw === 'string' ? sidRaw : null;
136
+ return {
137
+ requestId,
138
+ ok: true,
139
+ result: {
140
+ response: responseText,
141
+ session_id,
142
+ },
143
+ };
144
+ }
145
+ if (payload.ok === false) {
146
+ if (typeof payload.error !== 'string')
147
+ return null;
148
+ return { requestId, ok: false, error: payload.error };
149
+ }
150
+ return null;
151
+ }
105
152
 
106
- export { MINIAPP_CHANNEL, MINIAPP_VERSION, applyThemeToDocument, buildDataRequestMessage, buildReadyMessage, isTrustedMiniAppParentMessage, parseDataResponseMessage, parseThemeSyncMessage, resolveParentOriginFromReferrer };
153
+ export { MINIAPP_CHANNEL, MINIAPP_VERSION, applyThemeToDocument, buildChatSendMessage, buildDataRequestMessage, buildReadyMessage, isTrustedMiniAppParentMessage, parseChatSendResultMessage, parseDataResponseMessage, parseThemeSyncMessage, resolveParentOriginFromReferrer };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Default chart margins
3
+ */
4
+ export declare const CHART_MARGINS: {
5
+ readonly top: 20;
6
+ readonly right: 30;
7
+ readonly bottom: 20;
8
+ readonly left: -10;
9
+ };
@@ -65,13 +65,9 @@ declare function SidebarFooter({ className, ...props }: ComponentProps<'div'>):
65
65
  declare function SidebarSeparator({ className, ...props }: ComponentProps<typeof Separator>): import("react/jsx-runtime").JSX.Element;
66
66
  declare function SidebarContent({ className, innerClassName, children, }: ComponentProps<typeof Scroll>): import("react/jsx-runtime").JSX.Element;
67
67
  declare function SidebarGroup({ className, ...props }: ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
68
- declare function SidebarGroupLabel({ className, asChild, ...props }: ComponentProps<'div'> & {
69
- asChild?: boolean;
70
- }): import("react/jsx-runtime").JSX.Element;
71
68
  declare function SidebarGroupAction({ className, asChild, ...props }: ComponentProps<'button'> & {
72
69
  asChild?: boolean;
73
70
  }): import("react/jsx-runtime").JSX.Element;
74
- declare function SidebarGroupContent({ className, ...props }: ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
75
71
  declare function SidebarMenu({ className, ...props }: ComponentProps<'ul'>): import("react/jsx-runtime").JSX.Element;
76
72
  declare function SidebarMenuItem({ className, ...props }: ComponentProps<'li'>): import("react/jsx-runtime").JSX.Element;
77
73
  declare function SidebarMenuButton({ asChild, isActive, variant, size, className, ...props }: ButtonProps & {
@@ -90,4 +86,4 @@ declare function SidebarMenuSubButton({ asChild, size, isActive, tooltip, classN
90
86
  isActive?: boolean;
91
87
  tooltip?: string | ComponentProps<typeof TooltipContent>;
92
88
  }): import("react/jsx-runtime").JSX.Element;
93
- export { PanelResizeHandle, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarResizeHandle, SidebarSeparator, SidebarTrigger, useSidebar, };
89
+ export { PanelResizeHandle, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarResizeHandle, SidebarSeparator, SidebarTrigger, useSidebar, };
@@ -1,9 +1,10 @@
1
- export { applyThemeToDocument, buildDataRequestMessage, buildReadyMessage, MINIAPP_CHANNEL, MINIAPP_VERSION, parseDataResponseMessage, parseThemeSyncMessage, isTrustedMiniAppParentMessage, resolveParentOriginFromReferrer, } from './miniAppProtocol';
2
- export type { MiniAppMessageReady, MiniAppMessageThemeSync, MiniAppMessageDataRequest, MiniAppMessageDataResponse, MiniAppDataRequestPayload, MiniAppDataResponsePayload, MiniAppDataOp, ThemeSyncPayload, } from './miniAppProtocol';
1
+ export { applyThemeToDocument, buildChatSendMessage, buildDataRequestMessage, buildReadyMessage, MINIAPP_CHANNEL, MINIAPP_VERSION, parseChatSendResultMessage, parseDataResponseMessage, parseThemeSyncMessage, isTrustedMiniAppParentMessage, resolveParentOriginFromReferrer, } from './miniAppProtocol';
2
+ export type { MiniAppMessageReady, MiniAppMessageThemeSync, MiniAppMessageDataRequest, MiniAppMessageDataResponse, MiniAppMessageChatSend, MiniAppMessageChatSendResult, MiniAppDataRequestPayload, MiniAppDataResponsePayload, MiniAppChatSendPayload, MiniAppChatSendResultPayload, MiniAppDataOp, ThemeSyncPayload, } from './miniAppProtocol';
3
3
  export { createMiniAppDataClient } from './miniAppDataClient';
4
4
  export type { MiniAppDataClientOptions, MiniAppDataClient, } from './miniAppDataClient';
5
5
  export type { MiniAppDataset, MiniAppDriversComparisonSnapshot, MiniAppForecastMap, MiniAppPerformanceBundle, } from './miniAppDataTypes';
6
6
  export { getDefaultMiniAppThemeConfig } from './miniAppThemeConfig';
7
7
  export type { MiniAppThemeConfig } from './miniAppThemeConfig';
8
+ export { sendChatMessage } from './miniAppChatBridge';
8
9
  export { MiniAppRoot, useMiniAppShellTheme } from './MiniAppRoot';
9
10
  export type { MiniAppRootProps, MiniAppShellContextValue } from './MiniAppRoot';
@@ -0,0 +1,6 @@
1
+ import type { ChatResponse } from '#uilib/types/chat-api.types';
2
+ /**
3
+ * Ask the Sybilion host to send a chat message with its auth token.
4
+ * Does not update host ChatSheet state — same session as `chatId` on the agent only.
5
+ */
6
+ export declare function sendChatMessage(chatId: string, message: string): Promise<ChatResponse>;
@@ -2,6 +2,7 @@
2
2
  * postMessage protocol for Sybilion workspace mini-apps (iframe child).
3
3
  * Keep in sync with sybilion-client `src/workspace/miniAppBridge.ts` (channel, version, payloads).
4
4
  */
5
+ import type { ChatResponse } from '#uilib/types/chat-api.types';
5
6
  export declare const MINIAPP_CHANNEL: "sybilion.miniapp";
6
7
  export declare const MINIAPP_VERSION: 1;
7
8
  export type ThemeSyncPayload = {
@@ -46,6 +47,32 @@ export type MiniAppMessageDataResponse = {
46
47
  type: 'DATA_RESPONSE';
47
48
  payload: MiniAppDataResponsePayload;
48
49
  };
50
+ export type MiniAppChatSendPayload = {
51
+ requestId: string;
52
+ chatId: string;
53
+ message: string;
54
+ };
55
+ export type MiniAppMessageChatSend = {
56
+ channel: typeof MINIAPP_CHANNEL;
57
+ version: typeof MINIAPP_VERSION;
58
+ type: 'CHAT_SEND';
59
+ payload: MiniAppChatSendPayload;
60
+ };
61
+ export type MiniAppChatSendResultPayload = {
62
+ requestId: string;
63
+ ok: true;
64
+ result: ChatResponse;
65
+ } | {
66
+ requestId: string;
67
+ ok: false;
68
+ error: string;
69
+ };
70
+ export type MiniAppMessageChatSendResult = {
71
+ channel: typeof MINIAPP_CHANNEL;
72
+ version: typeof MINIAPP_VERSION;
73
+ type: 'CHAT_SEND_RESULT';
74
+ payload: MiniAppChatSendResultPayload;
75
+ };
49
76
  /** Parse parent → child THEME_SYNC (shell uses `buildThemeSyncMessage`). */
50
77
  export declare function parseThemeSyncMessage(data: unknown): ThemeSyncPayload | null;
51
78
  /** Child → parent READY (optional `appId` for telemetry). */
@@ -55,5 +82,8 @@ export declare function applyThemeToDocument(mode: 'light' | 'dark'): void;
55
82
  /** Only accept shell messages that appear to come from the real embedding parent. */
56
83
  export declare function isTrustedMiniAppParentMessage(event: MessageEvent): boolean;
57
84
  export declare function buildDataRequestMessage(payload: MiniAppDataRequestPayload): MiniAppMessageDataRequest;
85
+ export declare function buildChatSendMessage(payload: MiniAppChatSendPayload): MiniAppMessageChatSend;
58
86
  /** Parse parent → child DATA_RESPONSE. */
59
87
  export declare function parseDataResponseMessage(data: unknown): MiniAppDataResponsePayload | null;
88
+ /** Parse parent → child CHAT_SEND_RESULT (shell uses `buildChatSendResultMessage`). */
89
+ export declare function parseChatSendResultMessage(data: unknown): MiniAppChatSendResultPayload | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sybilion/uilib",
3
- "version": "1.0.31",
3
+ "version": "1.1.0",
4
4
  "description": "Sybilion Design System — React UI components (Webpack + Stylus)",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Default chart margins
3
+ */
4
+ export const CHART_MARGINS = {
5
+ top: 20,
6
+ right: 30,
7
+ bottom: 20,
8
+ left: -10,
9
+ } as const;
@@ -10,6 +10,7 @@ import { InteractionOverlay } from '#uilib/components/ui/InteractionOverlay/Inte
10
10
  import { TimeRangeControls } from '#uilib/components/ui/TimeRangeControls/TimeRangeControls';
11
11
  import { ensureChartForecastBridge } from '#uilib/utils/chartConnectionPoint';
12
12
 
13
+ import { CHART_MARGINS } from './ChartAreaInteractive.constants';
13
14
  import {
14
15
  filterDataForTimeRange,
15
16
  longDateFormatter,
@@ -151,7 +152,7 @@ export function ChartAreaInteractive({
151
152
  formatDate: shortDateFormatter,
152
153
  labelFormatter: (v: unknown) => longDateFormatter(v as string),
153
154
  chartType: 'composed' as const,
154
- margin: { left: -10, right: 30, top: 20, bottom: 20 },
155
+ margin: { ...CHART_MARGINS },
155
156
  hiddenSeries: seriesHidden,
156
157
  onLegendClick: handleLegendClick,
157
158
  onAnalysisSelect: onAnalysisSelect,
@@ -278,11 +278,6 @@
278
278
  &[data-collapsible="icon"]
279
279
  display none
280
280
 
281
- // Sidebar group content
282
- .sidebarGroupContent
283
- width 100%
284
- font-size 0.875rem
285
-
286
281
  // Sidebar menu
287
282
  .sidebarMenu
288
283
  display flex
@@ -11,7 +11,6 @@ interface CssExports {
11
11
  'sidebarFooter': string;
12
12
  'sidebarGroup': string;
13
13
  'sidebarGroupAction': string;
14
- 'sidebarGroupContent': string;
15
14
  'sidebarGroupLabel': string;
16
15
  'sidebarHeader': string;
17
16
  'sidebarInput': string;
@@ -738,23 +738,6 @@ function SidebarGroup({ className, ...props }: ComponentProps<'div'>) {
738
738
  );
739
739
  }
740
740
 
741
- function SidebarGroupLabel({
742
- className,
743
- asChild = false,
744
- ...props
745
- }: ComponentProps<'div'> & { asChild?: boolean }) {
746
- const Comp = asChild ? Slot : 'div';
747
-
748
- return (
749
- <Comp
750
- data-slot="sidebar-group-label"
751
- data-sidebar="group-label"
752
- className={cn(S.sidebarGroupLabel, className)}
753
- {...props}
754
- />
755
- );
756
- }
757
-
758
741
  function SidebarGroupAction({
759
742
  className,
760
743
  asChild = false,
@@ -772,17 +755,6 @@ function SidebarGroupAction({
772
755
  );
773
756
  }
774
757
 
775
- function SidebarGroupContent({ className, ...props }: ComponentProps<'div'>) {
776
- return (
777
- <div
778
- data-slot="sidebar-group-content"
779
- data-sidebar="group-content"
780
- className={cn(S.sidebarGroupContent, className)}
781
- {...props}
782
- />
783
- );
784
- }
785
-
786
758
  function SidebarMenu({ className, ...props }: ComponentProps<'ul'>) {
787
759
  return (
788
760
  <ul
@@ -952,8 +924,6 @@ export {
952
924
  SidebarFooter,
953
925
  SidebarGroup,
954
926
  SidebarGroupAction,
955
- SidebarGroupContent,
956
- SidebarGroupLabel,
957
927
  SidebarMenu,
958
928
  SidebarMenuAction,
959
929
  SidebarMenuBadge,
@@ -6,7 +6,6 @@ import {
6
6
  Sidebar,
7
7
  SidebarContent,
8
8
  SidebarGroup,
9
- SidebarGroupContent,
10
9
  SidebarMenu,
11
10
  SidebarMenuButton,
12
11
  SidebarMenuItem,
@@ -106,58 +105,56 @@ export function DocsSidebar() {
106
105
  />
107
106
  </SidebarMenu>
108
107
  <SidebarGroup>
109
- <SidebarGroupContent>
110
- <SidebarMenu>
111
- {DOC_SECTION_ORDER.map(section => {
112
- const entries = bySection.get(section);
113
- if (!entries?.length) return null;
108
+ <SidebarMenu>
109
+ {DOC_SECTION_ORDER.map(section => {
110
+ const entries = bySection.get(section);
111
+ if (!entries?.length) return null;
114
112
 
115
- const filteredEntries = isFiltering
116
- ? entries.filter(e => entryMatchesQuery(e, q))
117
- : entries;
118
- if (!filteredEntries.length) return null;
113
+ const filteredEntries = isFiltering
114
+ ? entries.filter(e => entryMatchesQuery(e, q))
115
+ : entries;
116
+ if (!filteredEntries.length) return null;
119
117
 
120
- const isExpanded = isFiltering || expandedSections.has(section);
121
- const sectionHasActive = entries.some(
122
- e => location.pathname === `/docs/${e.slug}`,
123
- );
118
+ const isExpanded = isFiltering || expandedSections.has(section);
119
+ const sectionHasActive = entries.some(
120
+ e => location.pathname === `/docs/${e.slug}`,
121
+ );
124
122
 
125
- return (
126
- <SidebarMenuItem key={section}>
127
- <SidebarMenuButton
128
- type="button"
129
- onClick={() => {
130
- if (!isFiltering) toggleSection(section);
131
- }}
132
- isActive={sectionHasActive}
133
- >
134
- <span>{section}</span>
135
- {isFiltering ? null : renderSectionChevron(isExpanded)}
136
- </SidebarMenuButton>
137
- {isExpanded ? (
138
- <SidebarMenuSub>
139
- {filteredEntries.map(e => {
140
- const to = `/docs/${e.slug}`;
141
- const isActive = location.pathname === to;
142
- return (
143
- <SidebarMenuSubItem key={e.slug}>
144
- <SidebarMenuSubButton
145
- asChild
146
- isActive={isActive}
147
- size="md"
148
- >
149
- <Link to={to}>{e.title}</Link>
150
- </SidebarMenuSubButton>
151
- </SidebarMenuSubItem>
152
- );
153
- })}
154
- </SidebarMenuSub>
155
- ) : null}
156
- </SidebarMenuItem>
157
- );
158
- })}
159
- </SidebarMenu>
160
- </SidebarGroupContent>
123
+ return (
124
+ <SidebarMenuItem key={section}>
125
+ <SidebarMenuButton
126
+ type="button"
127
+ onClick={() => {
128
+ if (!isFiltering) toggleSection(section);
129
+ }}
130
+ isActive={sectionHasActive}
131
+ >
132
+ <span>{section}</span>
133
+ {isFiltering ? null : renderSectionChevron(isExpanded)}
134
+ </SidebarMenuButton>
135
+ {isExpanded ? (
136
+ <SidebarMenuSub>
137
+ {filteredEntries.map(e => {
138
+ const to = `/docs/${e.slug}`;
139
+ const isActive = location.pathname === to;
140
+ return (
141
+ <SidebarMenuSubItem key={e.slug}>
142
+ <SidebarMenuSubButton
143
+ asChild
144
+ isActive={isActive}
145
+ size="md"
146
+ >
147
+ <Link to={to}>{e.title}</Link>
148
+ </SidebarMenuSubButton>
149
+ </SidebarMenuSubItem>
150
+ );
151
+ })}
152
+ </SidebarMenuSub>
153
+ ) : null}
154
+ </SidebarMenuItem>
155
+ );
156
+ })}
157
+ </SidebarMenu>
161
158
  </SidebarGroup>
162
159
  </SidebarContent>
163
160
  </Sidebar>
@@ -1,8 +1,6 @@
1
1
  import { PageContentSection } from '#uilib/components/ui/Page';
2
2
  import {
3
3
  SidebarGroup,
4
- SidebarGroupContent,
5
- SidebarGroupLabel,
6
4
  SidebarMenu,
7
5
  SidebarMenuButton,
8
6
  SidebarMenuItem,
@@ -20,32 +18,27 @@ export default function SidebarPage() {
20
18
  subheader="Sidebar menu primitives (isolated preview)."
21
19
  actions={<DocsHeaderActions />}
22
20
  />
23
- <PageContentSection
24
- style={{
25
- border: '1px solid var(--border)',
26
- borderRadius: 8,
27
- padding: 12,
28
- maxWidth: 280,
29
- background: 'var(--sidebar)',
30
- color: 'var(--sidebar-foreground)',
31
- }}
32
- >
33
- <SidebarGroup>
34
- <SidebarGroupLabel>Demo</SidebarGroupLabel>
35
- <SidebarGroupContent>
36
- <SidebarMenu>
37
- <SidebarMenuItem>
38
- <SidebarMenuButton type="button" isActive>
39
- Active item
40
- </SidebarMenuButton>
41
- </SidebarMenuItem>
42
- <SidebarMenuItem>
43
- <SidebarMenuButton type="button">
44
- Another item
45
- </SidebarMenuButton>
46
- </SidebarMenuItem>
47
- </SidebarMenu>
48
- </SidebarGroupContent>
21
+ <PageContentSection>
22
+ <SidebarGroup
23
+ style={{
24
+ maxWidth: 320,
25
+ padding: 12,
26
+ background: 'var(--sidebar)',
27
+ color: 'var(--sidebar-foreground)',
28
+ border: '1px solid var(--border)',
29
+ borderRadius: 'var(--p-4)',
30
+ }}
31
+ >
32
+ <SidebarMenu>
33
+ <SidebarMenuItem>
34
+ <SidebarMenuButton type="button" isActive>
35
+ Active item
36
+ </SidebarMenuButton>
37
+ </SidebarMenuItem>
38
+ <SidebarMenuItem>
39
+ <SidebarMenuButton type="button">Another item</SidebarMenuButton>
40
+ </SidebarMenuItem>
41
+ </SidebarMenu>
49
42
  </SidebarGroup>
50
43
  </PageContentSection>
51
44
  </>
@@ -1,9 +1,11 @@
1
1
  export {
2
2
  applyThemeToDocument,
3
+ buildChatSendMessage,
3
4
  buildDataRequestMessage,
4
5
  buildReadyMessage,
5
6
  MINIAPP_CHANNEL,
6
7
  MINIAPP_VERSION,
8
+ parseChatSendResultMessage,
7
9
  parseDataResponseMessage,
8
10
  parseThemeSyncMessage,
9
11
  isTrustedMiniAppParentMessage,
@@ -14,8 +16,12 @@ export type {
14
16
  MiniAppMessageThemeSync,
15
17
  MiniAppMessageDataRequest,
16
18
  MiniAppMessageDataResponse,
19
+ MiniAppMessageChatSend,
20
+ MiniAppMessageChatSendResult,
17
21
  MiniAppDataRequestPayload,
18
22
  MiniAppDataResponsePayload,
23
+ MiniAppChatSendPayload,
24
+ MiniAppChatSendResultPayload,
19
25
  MiniAppDataOp,
20
26
  ThemeSyncPayload,
21
27
  } from './miniAppProtocol';
@@ -32,5 +38,6 @@ export type {
32
38
  } from './miniAppDataTypes';
33
39
  export { getDefaultMiniAppThemeConfig } from './miniAppThemeConfig';
34
40
  export type { MiniAppThemeConfig } from './miniAppThemeConfig';
41
+ export { sendChatMessage } from './miniAppChatBridge';
35
42
  export { MiniAppRoot, useMiniAppShellTheme } from './MiniAppRoot';
36
43
  export type { MiniAppRootProps, MiniAppShellContextValue } from './MiniAppRoot';
@@ -0,0 +1,55 @@
1
+ import type { ChatResponse } from '#uilib/types/chat-api.types';
2
+
3
+ import {
4
+ buildChatSendMessage,
5
+ isTrustedMiniAppParentMessage,
6
+ parseChatSendResultMessage,
7
+ resolveParentOriginFromReferrer,
8
+ } from './miniAppProtocol';
9
+
10
+ const DEFAULT_TIMEOUT_MS = 60_000;
11
+
12
+ /**
13
+ * Ask the Sybilion host to send a chat message with its auth token.
14
+ * Does not update host ChatSheet state — same session as `chatId` on the agent only.
15
+ */
16
+ export async function sendChatMessage(
17
+ chatId: string,
18
+ message: string,
19
+ ): Promise<ChatResponse> {
20
+ if (typeof window === 'undefined' || window.parent === window) {
21
+ throw new Error('sendChatMessage requires an embedded mini-app (iframe)');
22
+ }
23
+
24
+ const requestId = crypto.randomUUID();
25
+ const target = resolveParentOriginFromReferrer();
26
+ const payload = { requestId, chatId, message };
27
+ const msg = buildChatSendMessage(payload);
28
+
29
+ return new Promise((resolve, reject) => {
30
+ const onMessage = (event: MessageEvent) => {
31
+ if (!isTrustedMiniAppParentMessage(event)) return;
32
+ const parsed = parseChatSendResultMessage(event.data);
33
+ if (!parsed || parsed.requestId !== requestId) return;
34
+ window.removeEventListener('message', onMessage);
35
+ clearTimeout(timer);
36
+ if (parsed.ok === true) {
37
+ resolve(parsed.result);
38
+ return;
39
+ }
40
+ reject(new Error(parsed.error));
41
+ };
42
+
43
+ window.addEventListener('message', onMessage);
44
+ const timer = setTimeout(() => {
45
+ window.removeEventListener('message', onMessage);
46
+ reject(new Error('Mini-app chat request timed out'));
47
+ }, DEFAULT_TIMEOUT_MS);
48
+
49
+ if (target) {
50
+ window.parent.postMessage(msg, target);
51
+ } else {
52
+ window.parent.postMessage(msg, '*');
53
+ }
54
+ });
55
+ }
@@ -2,6 +2,7 @@
2
2
  * postMessage protocol for Sybilion workspace mini-apps (iframe child).
3
3
  * Keep in sync with sybilion-client `src/workspace/miniAppBridge.ts` (channel, version, payloads).
4
4
  */
5
+ import type { ChatResponse } from '#uilib/types/chat-api.types';
5
6
 
6
7
  export const MINIAPP_CHANNEL = 'sybilion.miniapp' as const;
7
8
  export const MINIAPP_VERSION = 1 as const;
@@ -61,6 +62,38 @@ export type MiniAppMessageDataResponse = {
61
62
  payload: MiniAppDataResponsePayload;
62
63
  };
63
64
 
65
+ export type MiniAppChatSendPayload = {
66
+ requestId: string;
67
+ chatId: string;
68
+ message: string;
69
+ };
70
+
71
+ export type MiniAppMessageChatSend = {
72
+ channel: typeof MINIAPP_CHANNEL;
73
+ version: typeof MINIAPP_VERSION;
74
+ type: 'CHAT_SEND';
75
+ payload: MiniAppChatSendPayload;
76
+ };
77
+
78
+ export type MiniAppChatSendResultPayload =
79
+ | {
80
+ requestId: string;
81
+ ok: true;
82
+ result: ChatResponse;
83
+ }
84
+ | {
85
+ requestId: string;
86
+ ok: false;
87
+ error: string;
88
+ };
89
+
90
+ export type MiniAppMessageChatSendResult = {
91
+ channel: typeof MINIAPP_CHANNEL;
92
+ version: typeof MINIAPP_VERSION;
93
+ type: 'CHAT_SEND_RESULT';
94
+ payload: MiniAppChatSendResultPayload;
95
+ };
96
+
64
97
  function isRecord(v: unknown): v is Record<string, unknown> {
65
98
  return typeof v === 'object' && v !== null && !Array.isArray(v);
66
99
  }
@@ -133,6 +166,17 @@ export function buildDataRequestMessage(
133
166
  };
134
167
  }
135
168
 
169
+ export function buildChatSendMessage(
170
+ payload: MiniAppChatSendPayload,
171
+ ): MiniAppMessageChatSend {
172
+ return {
173
+ channel: MINIAPP_CHANNEL,
174
+ version: MINIAPP_VERSION,
175
+ type: 'CHAT_SEND',
176
+ payload,
177
+ };
178
+ }
179
+
136
180
  /** Parse parent → child DATA_RESPONSE. */
137
181
  export function parseDataResponseMessage(
138
182
  data: unknown,
@@ -162,3 +206,42 @@ export function parseDataResponseMessage(
162
206
  }
163
207
  return base;
164
208
  }
209
+
210
+ /** Parse parent → child CHAT_SEND_RESULT (shell uses `buildChatSendResultMessage`). */
211
+ export function parseChatSendResultMessage(
212
+ data: unknown,
213
+ ): MiniAppChatSendResultPayload | null {
214
+ if (!isRecord(data)) return null;
215
+ if (data.channel !== MINIAPP_CHANNEL) return null;
216
+ if (data.version !== MINIAPP_VERSION) return null;
217
+ if (data.type !== 'CHAT_SEND_RESULT') return null;
218
+ const payload = data.payload;
219
+ if (!isRecord(payload)) return null;
220
+ const requestId = payload.requestId;
221
+ if (typeof requestId !== 'string' || requestId.length === 0) return null;
222
+
223
+ if (payload.ok === true) {
224
+ const result = payload.result;
225
+ if (!isRecord(result)) return null;
226
+ const responseText = result.response;
227
+ if (typeof responseText !== 'string') return null;
228
+ const sidRaw = result.session_id;
229
+ if (sidRaw !== undefined && sidRaw !== null && typeof sidRaw !== 'string')
230
+ return null;
231
+ const session_id: string | null =
232
+ typeof sidRaw === 'string' ? sidRaw : null;
233
+ return {
234
+ requestId,
235
+ ok: true,
236
+ result: {
237
+ response: responseText,
238
+ session_id,
239
+ },
240
+ };
241
+ }
242
+ if (payload.ok === false) {
243
+ if (typeof payload.error !== 'string') return null;
244
+ return { requestId, ok: false, error: payload.error };
245
+ }
246
+ return null;
247
+ }