Skip to content

Commit 987a5ec

Browse files
committed
nested side nav - fixed that path was not a proxy, removed padding, switch to ID instead of title for nesting items to avoid ambigouity
1 parent 87309f4 commit 987a5ec

File tree

5 files changed

+87
-40
lines changed

5 files changed

+87
-40
lines changed

library/src/components/sidenavigation/SideNavigation.tsx

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ function Container({
4747
return (
4848
<nav
4949
className={twMerge(
50-
"bg-surface text-text-subtle relative flex size-full flex-col overflow-hidden truncate py-4",
50+
"bg-surface text-text-subtle relative flex size-full flex-col overflow-hidden truncate",
5151
className,
5252
)}
5353
role={role}
@@ -453,6 +453,7 @@ type _NestingItemProps = {
453453
style?: React.CSSProperties
454454
title: string // title is used to identify the item and as a key
455455
sideNavStoreIdent?: string
456+
id: string
456457
}
457458

458459
function NestingItem({
@@ -463,7 +464,7 @@ function NestingItem({
463464
title,
464465
_isOpen,
465466
id,
466-
}: _NestingItemProps & { _isOpen?: boolean; id?: string }) {
467+
}: _NestingItemProps & { _isOpen?: boolean }) {
467468
const {
468469
getCurrentPathElement,
469470
pushPathElement,
@@ -487,7 +488,7 @@ function NestingItem({
487488
return (
488489
<ButtonItem
489490
onClick={() => {
490-
pushPathElement(title)
491+
pushPathElement(id)
491492
setTransitioning(true)
492493
window.setTimeout(() => setTransitioning(null), animTime * 1000)
493494
}}
@@ -510,24 +511,26 @@ type _NestableNavigationContentProps = {
510511
className?: string
511512
style?: React.CSSProperties
512513
sideNavStoreIdent?: string
514+
onAnimationStart?: () => void
515+
onAnimationComplete?: () => void
513516
}
514517

515518
function searchChild(
516519
children: React.ReactNode,
517-
currentOpenedTitle: string | undefined,
520+
currentOpenedId: string | undefined,
518521
) {
519522
let renderChild: React.ReactElement<_NestingItemProps> | null = null
520523
React.Children.forEach(children, (child) => {
521524
if (renderChild) return
522525
if (
523526
React.isValidElement<_NestingItemProps>(child) &&
524-
child.props.title === currentOpenedTitle
527+
child.props.id === currentOpenedId
525528
) {
526529
renderChild = child
527530
return
528531
}
529532
if (React.isValidElement(child)) {
530-
const ret = searchChild(child.props.children, currentOpenedTitle)
533+
const ret = searchChild(child.props.children, currentOpenedId)
531534
if (ret) renderChild = ret
532535
}
533536
})
@@ -542,18 +545,18 @@ function NestableNavigationContent({
542545
sideNavStoreIdent = "default",
543546
className,
544547
style,
548+
onAnimationStart,
549+
onAnimationComplete,
545550
}: _NestableNavigationContentProps) {
546551
const { popPathElement, getCurrentPathElement, setTransitioning, path } =
547552
useSideNavigationStore(sideNavStoreIdent)
548553

549-
const currentOpenedTitle = getCurrentPathElement()
554+
const currentOpenedId = getCurrentPathElement()
550555

551-
const renderChild = currentOpenedTitle
552-
? searchChild(children, currentOpenedTitle)
556+
const renderChild = currentOpenedId
557+
? searchChild(children, currentOpenedId)
553558
: null
554559

555-
console.log("currentOpenedTitle", currentOpenedTitle, path, renderChild)
556-
557560
const [isBack, setIsBack] = useState(false)
558561

559562
return (
@@ -563,7 +566,7 @@ function NestableNavigationContent({
563566
>
564567
<AnimatePresence initial={false} mode="popLayout">
565568
{/* root level elements */}
566-
{!currentOpenedTitle && (
569+
{!currentOpenedId && (
567570
<motion.div
568571
key="outside"
569572
//layout
@@ -576,13 +579,19 @@ function NestableNavigationContent({
576579
duration: animTime,
577580
ease: "easeInOut",
578581
}}
582+
onAnimationStart={() => {
583+
onAnimationStart?.()
584+
}}
585+
onAnimationComplete={() => {
586+
onAnimationComplete?.()
587+
}}
579588
>
580589
{children}
581590
</motion.div>
582591
)}
583592
</AnimatePresence>
584593
<AnimatePresence initial={false} mode="popLayout">
585-
{currentOpenedTitle && (
594+
{currentOpenedId && (
586595
<motion.div
587596
key="go-back-btn"
588597
initial={{ x: "100%" }}
@@ -617,12 +626,14 @@ function NestableNavigationContent({
617626
<AnimatePresence
618627
initial={false}
619628
mode="popLayout"
620-
onExitComplete={() => setIsBack(false)}
629+
onExitComplete={() => {
630+
setIsBack(false)
631+
}}
621632
>
622633
{/* followed by the lower level elements */}
623-
{renderChild && (
634+
{renderChild != null && (
624635
<motion.div
625-
key={`inside-${currentOpenedTitle}`}
636+
key={`inside-${currentOpenedId}`}
626637
initial={{
627638
x: isBack ? "-100%" : "100%",
628639
}}
@@ -637,7 +648,13 @@ function NestableNavigationContent({
637648
ease: "easeInOut",
638649
//delay: animTime * 0.5,
639650
}}
640-
className="border-b-border-separator border-t-border-separator box-border flex size-full border-b-2 border-t-2 border-solid py-2"
651+
className="border-b-border-separator border-t-border-separator box-border flex size-full border-b-2 border-t-2 border-solid"
652+
onAnimationStart={() => {
653+
onAnimationStart?.()
654+
}}
655+
onAnimationComplete={() => {
656+
onAnimationComplete?.()
657+
}}
641658
>
642659
{React.cloneElement(renderChild, { _isOpen: true })}
643660
</motion.div>

library/src/components/sidenavigation/SideNavigationStore.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,20 @@ const store = proxy<Record<string, SideNavigationStore>>({})
1010

1111
export function useSideNavigationStore(sideNavStoreIdent: string) {
1212
if (!store[sideNavStoreIdent]) {
13-
store[sideNavStoreIdent] = {
13+
store[sideNavStoreIdent] = proxy<SideNavigationStore>({
1414
path: [],
1515
transitioning: null,
16-
}
16+
})
1717
}
1818

1919
const path = useSnapshot(store[sideNavStoreIdent])
2020
const setPath = useCallback(
2121
(path: string[]) =>
22-
store[sideNavStoreIdent].path.splice(0, path.length, ...path),
22+
store[sideNavStoreIdent].path.splice(
23+
0,
24+
Number.POSITIVE_INFINITY,
25+
...path,
26+
),
2327
[sideNavStoreIdent],
2428
)
2529

library/src/utils/ErrorHandler.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { type AxiosError, isAxiosError } from "axios"
2-
import { Button, Toast } from "@linked-planet/ui-kit-ts"
2+
import { Button, Toast } from "../components/index"
33
import type { QueryClient } from "@tanstack/react-query"
44

55
// in the handler function the returned boolean states if after the handler the error handling is done

showcase/public/showcase-sources.txt

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6829,12 +6829,20 @@ function SideNavExample() {
68296829
</SideNavigation.NavigationHeader>
68306830
<SideNavigation.Content>
68316831
<SideNavigation.NestableNavigationContent sideNavStoreIdent="side-nav-store-showcase">
6832-
<SideNavigation.NestingItem title="test nesting">
6832+
<SideNavigation.NestingItem
6833+
title="test nesting"
6834+
sideNavStoreIdent="side-nav-store-showcase"
6835+
id="test-nesting"
6836+
>
68336837
<SideNavigation.ButtonItem>
68346838
Test Nested Button
68356839
</SideNavigation.ButtonItem>
68366840
<SideNavigation.NestableNavigationContent>
6837-
<SideNavigation.NestingItem title="inner nesting">
6841+
<SideNavigation.NestingItem
6842+
title="inner nesting"
6843+
sideNavStoreIdent="side-nav-store-showcase"
6844+
id="inner-nesting"
6845+
>
68386846
<SideNavigation.ButtonItem>
68396847
Inner Test Nested Button
68406848
</SideNavigation.ButtonItem>
@@ -7045,15 +7053,21 @@ function NestingSideNavExample() {
70457053
>
70467054
<SideNavigation.Content>
70477055
<SideNavigation.NestableNavigationContent>
7048-
<SideNavigation.NestingItem title="outer">
7049-
<SideNavigation.NestingItem title="inner">
7056+
<SideNavigation.NestingItem title="outer" id="outer">
7057+
<SideNavigation.NestingItem
7058+
title="inner"
7059+
id="inner"
7060+
>
70507061
<SideNavigation.Section title="Section">
70517062
<SideNavigation.SkeletonItem />
70527063
<SideNavigation.ButtonItem>
70537064
Inner Button
70547065
</SideNavigation.ButtonItem>
70557066
</SideNavigation.Section>
7056-
<SideNavigation.NestingItem title="inner2">
7067+
<SideNavigation.NestingItem
7068+
title="inner2"
7069+
id="inner2"
7070+
>
70577071
<SideNavigation.ButtonItem>
70587072
Inner Nested Button
70597073
</SideNavigation.ButtonItem>
@@ -7074,13 +7088,17 @@ function NestingSideNavExample() {
70747088
//#endregion side-nav-example-nesting
70757089

70767090
//#region infinite-side-nav-example
7077-
function NestingChildren({ count }: { count: number }) {
7078-
console.log("ATTACHING", count)
7079-
if (count > 10) return null
7080-
const newCount = count + 1
7091+
function nestingChildren({ count }: { count: number }) {
7092+
if (count > 5)
7093+
return <SideNavigation.ButtonItem>End</SideNavigation.ButtonItem>
70817094
return (
7082-
<SideNavigation.NestingItem title={`Level${newCount}`}>
7083-
<NestingChildren count={newCount} />
7095+
<SideNavigation.NestingItem
7096+
title={`Level${count}`}
7097+
id={`level-${count}`}
7098+
sideNavStoreIdent="side-nav-store-showcase-infinite"
7099+
>
7100+
{/* This needs to be in function calling form to avoid JSX from stop rendering the children, and therefore stopping the nesting */}
7101+
{nestingChildren({ count: count + 1 })}
70847102
</SideNavigation.NestingItem>
70857103
)
70867104
}
@@ -7093,8 +7111,8 @@ function InfiniteSideNavExample() {
70937111
aria-label="Side navigation"
70947112
>
70957113
<SideNavigation.Content>
7096-
<SideNavigation.NestableNavigationContent>
7097-
<NestingChildren count={0} />
7114+
<SideNavigation.NestableNavigationContent sideNavStoreIdent="side-nav-store-showcase-infinite">
7115+
{nestingChildren({ count: 0 })}
70987116
</SideNavigation.NestableNavigationContent>
70997117
</SideNavigation.Content>
71007118
</SideNavigation.Container>

showcase/src/components/showcase/wrapper/SideNavigationShowcase.tsx

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ function SideNavExample() {
3636
<SideNavigation.NestingItem
3737
title="test nesting"
3838
sideNavStoreIdent="side-nav-store-showcase"
39+
id="test-nesting"
3940
>
4041
<SideNavigation.ButtonItem>
4142
Test Nested Button
@@ -44,6 +45,7 @@ function SideNavExample() {
4445
<SideNavigation.NestingItem
4546
title="inner nesting"
4647
sideNavStoreIdent="side-nav-store-showcase"
48+
id="inner-nesting"
4749
>
4850
<SideNavigation.ButtonItem>
4951
Inner Test Nested Button
@@ -255,15 +257,21 @@ function NestingSideNavExample() {
255257
>
256258
<SideNavigation.Content>
257259
<SideNavigation.NestableNavigationContent>
258-
<SideNavigation.NestingItem title="outer">
259-
<SideNavigation.NestingItem title="inner">
260+
<SideNavigation.NestingItem title="outer" id="outer">
261+
<SideNavigation.NestingItem
262+
title="inner"
263+
id="inner"
264+
>
260265
<SideNavigation.Section title="Section">
261266
<SideNavigation.SkeletonItem />
262267
<SideNavigation.ButtonItem>
263268
Inner Button
264269
</SideNavigation.ButtonItem>
265270
</SideNavigation.Section>
266-
<SideNavigation.NestingItem title="inner2">
271+
<SideNavigation.NestingItem
272+
title="inner2"
273+
id="inner2"
274+
>
267275
<SideNavigation.ButtonItem>
268276
Inner Nested Button
269277
</SideNavigation.ButtonItem>
@@ -285,12 +293,12 @@ function NestingSideNavExample() {
285293

286294
//#region infinite-side-nav-example
287295
function nestingChildren({ count }: { count: number }) {
288-
if (count > 5)
289-
return <SideNavigation.ButtonItem>End</SideNavigation.ButtonItem>
296+
if (count > 5) return null
290297
return (
291298
<SideNavigation.NestingItem
292299
title={`Level${count}`}
293300
id={`level-${count}`}
301+
sideNavStoreIdent="side-nav-store-showcase-infinite"
294302
>
295303
{/* This needs to be in function calling form to avoid JSX from stop rendering the children, and therefore stopping the nesting */}
296304
{nestingChildren({ count: count + 1 })}
@@ -306,7 +314,7 @@ function InfiniteSideNavExample() {
306314
aria-label="Side navigation"
307315
>
308316
<SideNavigation.Content>
309-
<SideNavigation.NestableNavigationContent>
317+
<SideNavigation.NestableNavigationContent sideNavStoreIdent="side-nav-store-showcase-infinite">
310318
{nestingChildren({ count: 0 })}
311319
</SideNavigation.NestableNavigationContent>
312320
</SideNavigation.Content>

0 commit comments

Comments
 (0)