zudoku 0.3.0-dev.61 → 0.3.0-dev.63

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zudoku",
3
- "version": "0.3.0-dev.61",
3
+ "version": "0.3.0-dev.63",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
package/src/app/main.css CHANGED
@@ -137,10 +137,10 @@
137
137
  --slide-offset: -0.75rem;
138
138
  @apply overflow-hidden;
139
139
  }
140
- .CollapsibleContent[data-state="open"] {
140
+ [data-animate="true"] .CollapsibleContent[data-state="open"] {
141
141
  animation: slideDown 300ms var(--easing);
142
142
  }
143
- .CollapsibleContent[data-state="closed"] {
143
+ [data-animate="true"] .CollapsibleContent[data-state="closed"] {
144
144
  animation: slideUp 300ms var(--easing);
145
145
  }
146
146
 
@@ -54,28 +54,32 @@ export const Header = memo(function HeaderInner() {
54
54
  <header className="fixed top-0 w-full z-10 bg-background/80 backdrop-blur">
55
55
  <div className="max-w-screen-2xl mx-auto">
56
56
  <div className="grid grid-cols-[calc(var(--side-nav-width))_1fr] lg:gap-12 items-center border-b px-12 h-[--top-header-height]">
57
- <div className="flex items-center gap-3.5">
58
- {page?.logo && (
59
- <>
60
- <img
61
- src={page.logo.src.light}
62
- alt={page.logo.alt ?? page.pageTitle}
63
- style={{ width: page.logo.width }}
64
- className={cn("h-10", isDark && "hidden")}
65
- loading="lazy"
66
- />
67
- <img
68
- src={page.logo.src.dark}
69
- alt={page.logo.alt ?? page.pageTitle}
70
- style={{ width: page.logo.width }}
71
- className={cn("h-10", !isDark && "hidden")}
72
- loading="lazy"
73
- />
74
- </>
75
- )}
76
- <span className="font-bold text-2xl text-foreground/85 tracking-wide">
77
- {page?.pageTitle}
78
- </span>
57
+ <div className="flex">
58
+ <Link to="/">
59
+ <div className="flex items-center gap-3.5">
60
+ {page?.logo && (
61
+ <>
62
+ <img
63
+ src={page.logo.src.light}
64
+ alt={page.logo.alt ?? page.pageTitle}
65
+ style={{ width: page.logo.width }}
66
+ className={cn("h-10", isDark && "hidden")}
67
+ loading="lazy"
68
+ />
69
+ <img
70
+ src={page.logo.src.dark}
71
+ alt={page.logo.alt ?? page.pageTitle}
72
+ style={{ width: page.logo.width }}
73
+ className={cn("h-10", !isDark && "hidden")}
74
+ loading="lazy"
75
+ />
76
+ </>
77
+ )}
78
+ <span className="font-bold text-2xl text-foreground/85 tracking-wide">
79
+ {page?.pageTitle}
80
+ </span>
81
+ </div>
82
+ </Link>
79
83
  </div>
80
84
  <div className="grid grid-cols-[--sidecar-grid-cols] items-center gap-8">
81
85
  <div className="w-full max-w-prose">
@@ -21,7 +21,7 @@ export const SideNavigationCategory = ({
21
21
 
22
22
  const isCollapsible = category.collapsible ?? true;
23
23
 
24
- const [isOpen, setIsOpen] = useNavigationCollapsibleState({
24
+ const collapsibleProps = useNavigationCollapsibleState({
25
25
  item: category,
26
26
  path: navItem?.path ?? "",
27
27
  defaultOpen: () =>
@@ -31,11 +31,7 @@ export const SideNavigationCategory = ({
31
31
  });
32
32
 
33
33
  return (
34
- <Collapsible.Root
35
- key={category.label}
36
- open={isOpen}
37
- onOpenChange={() => setIsOpen((prev) => !prev)}
38
- >
34
+ <Collapsible.Root key={category.label} {...collapsibleProps}>
39
35
  {category.label.length > 0 ? (
40
36
  <Collapsible.Trigger asChild={isCollapsible} disabled={!isCollapsible}>
41
37
  <h5
@@ -14,7 +14,7 @@ import { AnchorLink } from "../AnchorLink.js";
14
14
  import { useNavigationCollapsibleState } from "./useNavigationCollapsibleState.js";
15
15
  import { checkHasActiveItem, isLinkItem, isPathItem } from "./util.js";
16
16
 
17
- export const navigationListItem = cva(
17
+ const navigationListItem = cva(
18
18
  "flex px-[--padding-nav-item] py-1.5 rounded-lg hover:bg-accent transition-colors duration-300",
19
19
  {
20
20
  variants: {
@@ -48,10 +48,10 @@ export const SideNavigationItem = ({
48
48
  const currentPath = isPathItem(item) ? joinPath(basePath, item.path) : "";
49
49
  const location = useLocation();
50
50
 
51
- const [isOpen, setIsOpen] = useNavigationCollapsibleState({
51
+ const collapsibleProps = useNavigationCollapsibleState({
52
52
  item,
53
53
  path: currentPath,
54
- defaultOpen: () => checkHasActiveItem(item, location.pathname, currentPath),
54
+ defaultOpen: () => checkHasActiveItem(item, location.pathname, basePath),
55
55
  });
56
56
 
57
57
  if (isLinkItem(item)) {
@@ -100,11 +100,7 @@ export const SideNavigationItem = ({
100
100
  return (
101
101
  <li title={typeof item.label === "string" ? item.label : item.title}>
102
102
  {item.children ? (
103
- <Collapsible.Root
104
- open={isOpen}
105
- onOpenChange={() => setIsOpen((prev) => !prev)}
106
- className="flex flex-col"
107
- >
103
+ <Collapsible.Root {...collapsibleProps} className="flex flex-col">
108
104
  <Collapsible.Trigger
109
105
  className={cn(
110
106
  "group text-start",
@@ -1,3 +1,4 @@
1
+ import type { CollapsibleProps } from "@radix-ui/react-collapsible";
1
2
  import { useEffect, useRef, useState } from "react";
2
3
  import { useLocation } from "react-router-dom";
3
4
  import type { NavigationNode } from "../../util/traverseNavigation.js";
@@ -11,17 +12,31 @@ export const useNavigationCollapsibleState = ({
11
12
  item: NavigationNode;
12
13
  defaultOpen: () => boolean;
13
14
  path: string;
14
- }) => {
15
- const [isOpen, setIsOpen] = useState(defaultOpen);
15
+ }): Partial<CollapsibleProps> & { "data-animate": boolean } => {
16
+ const [open, setOpen] = useState(defaultOpen);
16
17
  const location = useLocation();
17
18
  const previousLocationPath = useRef(location.pathname);
19
+ const [shouldAnimate, setShouldAnimate] = useState(false);
18
20
 
19
21
  useEffect(() => {
20
- if (!isOpen && previousLocationPath.current !== location.pathname) {
21
- setIsOpen(checkHasActiveItem(item, location.pathname, path));
22
+ if (!open && previousLocationPath.current !== location.pathname) {
23
+ setOpen(checkHasActiveItem(item, location.pathname, path));
22
24
  }
23
25
  previousLocationPath.current = location.pathname;
24
- }, [isOpen, item, path, location.pathname]);
26
+ }, [open, item, path, location.pathname]);
25
27
 
26
- return [isOpen, setIsOpen] as const;
28
+ const onOpenChange = () => {
29
+ setShouldAnimate(true);
30
+ setOpen((prev) => !prev);
31
+ };
32
+
33
+ useEffect(() => {
34
+ setShouldAnimate(false);
35
+ }, []);
36
+
37
+ return {
38
+ open,
39
+ onOpenChange,
40
+ "data-animate": shouldAnimate,
41
+ };
27
42
  };