Explorar el Código

wip(app): full-height sidebar

adamelmore hace 3 semanas
padre
commit
7016be0739
Se han modificado 2 ficheros con 13 adiciones y 11 borrados
  1. 10 9
      packages/app/src/pages/layout.tsx
  2. 3 2
      packages/ui/src/components/hover-card.tsx

+ 10 - 9
packages/app/src/pages/layout.tsx

@@ -137,7 +137,7 @@ export default function Layout(props: ParentProps) {
   const [hoverSession, setHoverSession] = createSignal<string | undefined>()
   const [hoverSession, setHoverSession] = createSignal<string | undefined>()
   const [hoverProject, setHoverProject] = createSignal<string | undefined>()
   const [hoverProject, setHoverProject] = createSignal<string | undefined>()
 
 
-  const navRef = { current: undefined as HTMLElement | undefined }
+  const [nav, setNav] = createSignal<HTMLElement | undefined>(undefined)
 
 
   const sidebarHovering = createMemo(() => !layout.sidebar.opened() && hoverProject() !== undefined)
   const sidebarHovering = createMemo(() => !layout.sidebar.opened() && hoverProject() !== undefined)
   const sidebarExpanded = createMemo(() => layout.sidebar.opened() || sidebarHovering())
   const sidebarExpanded = createMemo(() => layout.sidebar.opened() || sidebarHovering())
@@ -1702,10 +1702,11 @@ export default function Layout(props: ParentProps) {
         >
         >
           <HoverCard
           <HoverCard
             openDelay={1000}
             openDelay={1000}
-            closeDelay={0}
+            closeDelay={sidebarHovering() ? 300 : 0}
             placement="right"
             placement="right"
             gutter={28}
             gutter={28}
             trigger={item}
             trigger={item}
+            mount={!props.mobile ? nav() : undefined}
             open={hoverSession() === props.session.id}
             open={hoverSession() === props.session.id}
             onOpenChange={(open) => setHoverSession(open ? props.session.id : undefined)}
             onOpenChange={(open) => setHoverSession(open ? props.session.id : undefined)}
           >
           >
@@ -1743,7 +1744,7 @@ export default function Layout(props: ParentProps) {
             "group-focus-within/session:opacity-100 group-focus-within/session:pointer-events-auto": true,
             "group-focus-within/session:opacity-100 group-focus-within/session:pointer-events-auto": true,
           }}
           }}
         >
         >
-          <DropdownMenu open={menuOpen()} onOpenChange={setMenuOpen}>
+          <DropdownMenu modal={!sidebarHovering()} open={menuOpen()} onOpenChange={setMenuOpen}>
             <Tooltip value={language.t("common.moreOptions")} placement="top">
             <Tooltip value={language.t("common.moreOptions")} placement="top">
               <DropdownMenu.Trigger
               <DropdownMenu.Trigger
                 as={IconButton}
                 as={IconButton}
@@ -1753,7 +1754,7 @@ export default function Layout(props: ParentProps) {
                 aria-label={language.t("common.moreOptions")}
                 aria-label={language.t("common.moreOptions")}
               />
               />
             </Tooltip>
             </Tooltip>
-            <DropdownMenu.Portal mount={!props.mobile ? navRef.current : undefined}>
+            <DropdownMenu.Portal mount={!props.mobile ? nav() : undefined}>
               <DropdownMenu.Content
               <DropdownMenu.Content
                 onCloseAutoFocus={(event) => {
                 onCloseAutoFocus={(event) => {
                   if (!pendingRename()) return
                   if (!pendingRename()) return
@@ -1993,7 +1994,7 @@ export default function Layout(props: ParentProps) {
                     "group-focus-within/workspace:opacity-100 group-focus-within/workspace:pointer-events-auto": true,
                     "group-focus-within/workspace:opacity-100 group-focus-within/workspace:pointer-events-auto": true,
                   }}
                   }}
                 >
                 >
-                  <DropdownMenu open={menuOpen()} onOpenChange={setMenuOpen}>
+                  <DropdownMenu modal={!sidebarHovering()} open={menuOpen()} onOpenChange={setMenuOpen}>
                     <Tooltip value={language.t("common.moreOptions")} placement="top">
                     <Tooltip value={language.t("common.moreOptions")} placement="top">
                       <DropdownMenu.Trigger
                       <DropdownMenu.Trigger
                         as={IconButton}
                         as={IconButton}
@@ -2003,7 +2004,7 @@ export default function Layout(props: ParentProps) {
                         aria-label={language.t("common.moreOptions")}
                         aria-label={language.t("common.moreOptions")}
                       />
                       />
                     </Tooltip>
                     </Tooltip>
-                    <DropdownMenu.Portal mount={!props.mobile ? navRef.current : undefined}>
+                    <DropdownMenu.Portal mount={!props.mobile ? nav() : undefined}>
                       <DropdownMenu.Content
                       <DropdownMenu.Content
                         onCloseAutoFocus={(event) => {
                         onCloseAutoFocus={(event) => {
                           if (!pendingRename()) return
                           if (!pendingRename()) return
@@ -2411,7 +2412,7 @@ export default function Layout(props: ParentProps) {
                     </Tooltip>
                     </Tooltip>
                   </div>
                   </div>
 
 
-                  <DropdownMenu>
+                  <DropdownMenu modal={!sidebarHovering()}>
                     <DropdownMenu.Trigger
                     <DropdownMenu.Trigger
                       as={IconButton}
                       as={IconButton}
                       icon="dot-grid"
                       icon="dot-grid"
@@ -2419,7 +2420,7 @@ export default function Layout(props: ParentProps) {
                       class="shrink-0 size-6 rounded-md opacity-0 group-hover/project:opacity-100 data-[expanded]:opacity-100 data-[expanded]:bg-surface-base-active"
                       class="shrink-0 size-6 rounded-md opacity-0 group-hover/project:opacity-100 data-[expanded]:opacity-100 data-[expanded]:bg-surface-base-active"
                       aria-label={language.t("common.moreOptions")}
                       aria-label={language.t("common.moreOptions")}
                     />
                     />
-                    <DropdownMenu.Portal mount={!panelProps.mobile ? navRef.current : undefined}>
+                    <DropdownMenu.Portal mount={!panelProps.mobile ? nav() : undefined}>
                       <DropdownMenu.Content class="mt-1">
                       <DropdownMenu.Content class="mt-1">
                         <DropdownMenu.Item onSelect={() => dialog.show(() => <DialogEditProject project={p} />)}>
                         <DropdownMenu.Item onSelect={() => dialog.show(() => <DialogEditProject project={p} />)}>
                           <DropdownMenu.ItemLabel>{language.t("common.edit")}</DropdownMenu.ItemLabel>
                           <DropdownMenu.ItemLabel>{language.t("common.edit")}</DropdownMenu.ItemLabel>
@@ -2660,7 +2661,7 @@ export default function Layout(props: ParentProps) {
           }}
           }}
           style={{ width: layout.sidebar.opened() ? `${Math.max(layout.sidebar.width(), 244)}px` : "64px" }}
           style={{ width: layout.sidebar.opened() ? `${Math.max(layout.sidebar.width(), 244)}px` : "64px" }}
           ref={(el) => {
           ref={(el) => {
-            navRef.current = el
+            setNav(el)
           }}
           }}
           onMouseLeave={() => {
           onMouseLeave={() => {
             setHoverSession(undefined)
             setHoverSession(undefined)

+ 3 - 2
packages/ui/src/components/hover-card.tsx

@@ -3,19 +3,20 @@ import { ComponentProps, JSXElement, ParentProps, splitProps } from "solid-js"
 
 
 export interface HoverCardProps extends ParentProps, Omit<ComponentProps<typeof Kobalte>, "children"> {
 export interface HoverCardProps extends ParentProps, Omit<ComponentProps<typeof Kobalte>, "children"> {
   trigger: JSXElement
   trigger: JSXElement
+  mount?: HTMLElement
   class?: ComponentProps<"div">["class"]
   class?: ComponentProps<"div">["class"]
   classList?: ComponentProps<"div">["classList"]
   classList?: ComponentProps<"div">["classList"]
 }
 }
 
 
 export function HoverCard(props: HoverCardProps) {
 export function HoverCard(props: HoverCardProps) {
-  const [local, rest] = splitProps(props, ["trigger", "class", "classList", "children"])
+  const [local, rest] = splitProps(props, ["trigger", "mount", "class", "classList", "children"])
 
 
   return (
   return (
     <Kobalte gutter={4} {...rest}>
     <Kobalte gutter={4} {...rest}>
       <Kobalte.Trigger as="div" data-slot="hover-card-trigger">
       <Kobalte.Trigger as="div" data-slot="hover-card-trigger">
         {local.trigger}
         {local.trigger}
       </Kobalte.Trigger>
       </Kobalte.Trigger>
-      <Kobalte.Portal>
+      <Kobalte.Portal mount={local.mount}>
         <Kobalte.Content
         <Kobalte.Content
           data-component="hover-card-content"
           data-component="hover-card-content"
           classList={{
           classList={{