@exegia/corpora-ui 0.16.0 → 0.17.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.
- package/dist-lib/components/blocks/shell/shell-layout.d.ts +1 -1
- package/dist-lib/components/blocks/shell/type.d.ts +1 -0
- package/dist-lib/components/motion/animated-sidebar.d.ts +0 -3
- package/dist-lib/index.js +869 -877
- package/dist-lib/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/blocks/shell/__tests__/shell-layout.test.tsx +3 -3
- package/src/components/blocks/shell/shell-layout.tsx +27 -39
- package/src/components/blocks/shell/type.ts +1 -0
- package/src/components/motion/animated-sidebar.tsx +21 -46
- package/src/components/ui/button.tsx +3 -3
package/package.json
CHANGED
|
@@ -92,12 +92,12 @@ describe("ShellLayout", () => {
|
|
|
92
92
|
expect(rightDrawer().getAttribute("data-state")).toBe("expanded")
|
|
93
93
|
})
|
|
94
94
|
|
|
95
|
-
test("a panel's own
|
|
95
|
+
test("a panel's own defaultOpen flag seeds its side's initial state", () => {
|
|
96
96
|
render(
|
|
97
97
|
<ShellLayout
|
|
98
98
|
panels={{
|
|
99
99
|
...PANELS,
|
|
100
|
-
right: { ...PANELS.right!,
|
|
100
|
+
right: { ...PANELS.right!, defaultOpen: true },
|
|
101
101
|
}}
|
|
102
102
|
variant="web"
|
|
103
103
|
/>
|
|
@@ -112,7 +112,7 @@ describe("ShellLayout", () => {
|
|
|
112
112
|
defaultOpen={{ left: false, right: false }}
|
|
113
113
|
panels={{
|
|
114
114
|
...PANELS,
|
|
115
|
-
right: { ...PANELS.right!,
|
|
115
|
+
right: { ...PANELS.right!, defaultOpen: true },
|
|
116
116
|
}}
|
|
117
117
|
variant="web"
|
|
118
118
|
/>
|
|
@@ -19,6 +19,7 @@ export function ShellLayout({
|
|
|
19
19
|
variant = "desktop",
|
|
20
20
|
panels,
|
|
21
21
|
className,
|
|
22
|
+
header,
|
|
22
23
|
defaultOpen,
|
|
23
24
|
...panelControlProps
|
|
24
25
|
}: ShellLayoutProps): React.ReactElement {
|
|
@@ -29,22 +30,27 @@ export function ShellLayout({
|
|
|
29
30
|
// an explicit `defaultOpen` record — usually from useShellPanels — wins
|
|
30
31
|
// per side.
|
|
31
32
|
const initialOpen: ShellPanelControlProps["defaultOpen"] = {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
33
|
+
...(panels?.left && {
|
|
34
|
+
left: panels.left.defaultOpen ?? true,
|
|
35
|
+
}),
|
|
36
|
+
...(panels?.right && {
|
|
37
|
+
right: panels.right.defaultOpen ?? false,
|
|
38
|
+
}),
|
|
39
|
+
...defaultOpen,
|
|
40
|
+
}
|
|
41
|
+
|
|
40
42
|
|
|
41
43
|
return (
|
|
42
44
|
<AnimatedSidebarProvider
|
|
43
45
|
{...panelControlProps}
|
|
44
46
|
defaultOpen={initialOpen}
|
|
45
|
-
className={cn(
|
|
47
|
+
className={cn(
|
|
48
|
+
"relative block-full pr-2",
|
|
49
|
+
className,
|
|
50
|
+
background
|
|
51
|
+
)}
|
|
46
52
|
style={{
|
|
47
|
-
paddingTop: variant === "desktop" ? TITLE_BAR_HEIGHT : 0
|
|
53
|
+
paddingTop: variant === "desktop" ? TITLE_BAR_HEIGHT : 0,
|
|
48
54
|
}}
|
|
49
55
|
>
|
|
50
56
|
<AnimatedSidebar
|
|
@@ -56,24 +62,20 @@ export function ShellLayout({
|
|
|
56
62
|
{panels?.left?.component}
|
|
57
63
|
</AnimatedSidebar>
|
|
58
64
|
|
|
59
|
-
<AnimatedSidebarInset
|
|
60
|
-
className=
|
|
61
|
-
"min-w-
|
|
62
|
-
`mx-0!`
|
|
63
|
-
)}
|
|
64
|
-
>
|
|
65
|
-
<header className="flex h-16 items-center justify-between gap-3 px-4 sm:px-6">
|
|
66
|
-
<div className="flex min-w-0 items-center gap-3">
|
|
65
|
+
<AnimatedSidebarInset className="min-w-24">
|
|
66
|
+
<header className="flex h-12 items-center justify-between gap-2 px-2">
|
|
67
|
+
<div className="flex min-w-0 items-center gap-2">
|
|
67
68
|
<AnimatedSidebarTrigger>
|
|
68
69
|
{panels?.left?.trigger ?? (
|
|
69
70
|
<MotionIcon name="PanelLeft" size={24} animation="press" />
|
|
70
71
|
)}
|
|
71
72
|
</AnimatedSidebarTrigger>
|
|
72
73
|
</div>
|
|
73
|
-
<div className="flex
|
|
74
|
+
{header && <div className="flex flex-1 items-center">{header}</div>}
|
|
75
|
+
<div className="flex shrink-0 items-center gap-2">
|
|
74
76
|
<AnimatedSidebarTrigger aria-label="Toggle panel" side="right">
|
|
75
77
|
{panels?.right?.trigger ?? (
|
|
76
|
-
<MotionIcon name="PanelRight" size={24}
|
|
78
|
+
<MotionIcon className="opacity-70" name="PanelRight" size={24} />
|
|
77
79
|
)}
|
|
78
80
|
</AnimatedSidebarTrigger>
|
|
79
81
|
</div>
|
|
@@ -87,16 +89,10 @@ export function ShellLayout({
|
|
|
87
89
|
ariaLabel={panels?.right?.name ?? "Secondary panel"}
|
|
88
90
|
// Below md the panel is portal led over the page, so it carries the
|
|
89
91
|
// surface itself; the desktop rail keeps it on the inner panel.
|
|
90
|
-
className={cn(
|
|
91
|
-
|
|
92
|
-
panelClassName={cn(
|
|
93
|
-
// The off canvas panel keeps a fixed width so it can slide out of the
|
|
94
|
-
// zero-width rail, so the inset gutter has to come out of that width
|
|
95
|
-
// rather than from a left margin.
|
|
96
|
-
"top-2 ml-0 h-[calc(100%-1rem)] min-w-[calc(var(--sidebar-width))]",
|
|
97
|
-
"rounded-lg border-t border-neutral-200 bg-white shadow-md inset-ring-1 inset-ring-neutral-50",
|
|
98
|
-
"dark:border-neutral-700 dark:bg-card dark:inset-ring-black"
|
|
92
|
+
className={cn(
|
|
93
|
+
"max-md:border-l max-md:border-neutral-200 max-md:bg-white dark:max-md:border-neutral-700 dark:max-md:bg-card"
|
|
99
94
|
)}
|
|
95
|
+
collapsible="offcanvas"
|
|
100
96
|
role="complementary"
|
|
101
97
|
side="right"
|
|
102
98
|
variant="inset"
|
|
@@ -109,16 +105,8 @@ export function ShellLayout({
|
|
|
109
105
|
|
|
110
106
|
function ShellLayoutPlaceholder() {
|
|
111
107
|
return (
|
|
112
|
-
<div className="
|
|
113
|
-
<div className="
|
|
114
|
-
{Array.from({ length: 3 }).map((_, index) => (
|
|
115
|
-
<div
|
|
116
|
-
className="h-32 border border-border bg-background/60"
|
|
117
|
-
key={index}
|
|
118
|
-
/>
|
|
119
|
-
))}
|
|
120
|
-
</div>
|
|
121
|
-
<div className="h-72 border border-border bg-background/60" />
|
|
108
|
+
<div className="flex flex-col flex-1 p-4">
|
|
109
|
+
<div className="h-96 border border-border bg-muted-foreground/10 rounded-lg" />
|
|
122
110
|
</div>
|
|
123
111
|
)
|
|
124
112
|
}
|
|
@@ -91,6 +91,7 @@ export interface ShellLayoutProps extends ShellPanelControlProps {
|
|
|
91
91
|
/** Content for the shell's panels, keyed by the side. The shell renders
|
|
92
92
|
* the `left` rail and the `right` drawer; other sides are reserved. */
|
|
93
93
|
panels?: TPanelMap
|
|
94
|
+
header?: ReactNode
|
|
94
95
|
className?: string
|
|
95
96
|
variant?: "web" | "desktop"
|
|
96
97
|
}
|
|
@@ -29,6 +29,7 @@ import { createPortal } from "react-dom"
|
|
|
29
29
|
import { SharedLayoutBg } from "@/components/motion/shared-layout-bg"
|
|
30
30
|
import { EASE_DRAWER, EASE_OUT, SPRING_LAYOUT, SPRING_PRESS } from "@/lib/ease"
|
|
31
31
|
import { cn } from "@/lib/utils"
|
|
32
|
+
import { Button } from "@/components/ui/button";
|
|
32
33
|
|
|
33
34
|
export type SidebarSide = "left" | "right"
|
|
34
35
|
/** Open flags keyed by the side. Sides left out stay uncontrolled / at their
|
|
@@ -583,7 +584,9 @@ export const AnimatedSidebar = forwardRef<HTMLElement, AnimatedSidebarProps>(
|
|
|
583
584
|
)}
|
|
584
585
|
>
|
|
585
586
|
{side === "right" && !collapsed && (
|
|
586
|
-
<motion.div className="h-full
|
|
587
|
+
<motion.div className="flex h-full cursor-col-resize justify-center p-1 group relative">
|
|
588
|
+
<motion.div className="h-full w-full scale-y-0 animate-in bg-radial/decreasing from-amber-300/70 to-amber-500/0 to-40% transition-[colors,scale] duration-200 ease-smooth-out group-hover:scale-y-100 absolute" />
|
|
589
|
+
</motion.div>
|
|
587
590
|
)}
|
|
588
591
|
<motion.div
|
|
589
592
|
initial={false}
|
|
@@ -594,10 +597,19 @@ export const AnimatedSidebar = forwardRef<HTMLElement, AnimatedSidebarProps>(
|
|
|
594
597
|
transition={context.reduce ? REDUCED_TRANSITION : PANEL_TRANSITION}
|
|
595
598
|
className={cn(
|
|
596
599
|
"sticky top-0 flex h-svh w-full flex-col overflow-hidden",
|
|
600
|
+
"bg-neutral-50 dark:bg-neutral-900",
|
|
601
|
+
"outline-offset-0.5 border-t-3 border-white outline-neutral-100 dark:border-neutral-800 dark:inset-ring-black",
|
|
602
|
+
"rounded-lg shadow-md shadow-neutral-200 dark:shadow-neutral-950",
|
|
597
603
|
collapsible === "offcanvas" && "w-(--sidebar-width)",
|
|
598
604
|
|
|
599
605
|
variant === "floating" && "m-2 h-[calc(100svh-1rem)]",
|
|
600
|
-
variant === "inset" && "
|
|
606
|
+
variant === "inset" && "my-2 h-[calc(100svh-1rem)]",
|
|
607
|
+
variant === "inset" &&
|
|
608
|
+
side === "right" &&
|
|
609
|
+
"w-[calc(var(--sidebar-width)-0.5rem)]",
|
|
610
|
+
variant === "inset" &&
|
|
611
|
+
side === "left" &&
|
|
612
|
+
"border-transparent! bg-transparent! shadow-none!",
|
|
601
613
|
panelClassName
|
|
602
614
|
)}
|
|
603
615
|
>
|
|
@@ -620,7 +632,7 @@ export const AnimatedSidebarTrigger = forwardRef<
|
|
|
620
632
|
HTMLButtonElement,
|
|
621
633
|
AnimatedSidebarTriggerProps
|
|
622
634
|
>(function AnimatedSidebarTrigger(
|
|
623
|
-
{
|
|
635
|
+
{ onClick, side = "left", type = "button", ...props },
|
|
624
636
|
forwardedRef
|
|
625
637
|
) {
|
|
626
638
|
const context = useAnimatedSidebar()
|
|
@@ -630,7 +642,7 @@ export const AnimatedSidebarTrigger = forwardRef<
|
|
|
630
642
|
const triggerRef = context.triggerRefs[side]
|
|
631
643
|
|
|
632
644
|
return (
|
|
633
|
-
<
|
|
645
|
+
<Button
|
|
634
646
|
{...props}
|
|
635
647
|
ref={(node) => {
|
|
636
648
|
triggerRef.current = node
|
|
@@ -638,6 +650,8 @@ export const AnimatedSidebarTrigger = forwardRef<
|
|
|
638
650
|
else if (forwardedRef) forwardedRef.current = node
|
|
639
651
|
}}
|
|
640
652
|
type={type}
|
|
653
|
+
variant="ghost"
|
|
654
|
+
size="icon-xl"
|
|
641
655
|
aria-label={props["aria-label"] ?? "Toggle sidebar"}
|
|
642
656
|
aria-expanded={expanded}
|
|
643
657
|
data-slot="sidebar-trigger"
|
|
@@ -648,11 +662,6 @@ export const AnimatedSidebarTrigger = forwardRef<
|
|
|
648
662
|
if (event.defaultPrevented) return
|
|
649
663
|
context.toggleSidebar(side)
|
|
650
664
|
}}
|
|
651
|
-
className={cn(
|
|
652
|
-
"inline-flex size-10 shrink-0 items-center justify-center rounded-xl outline-none",
|
|
653
|
-
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
654
|
-
className
|
|
655
|
-
)}
|
|
656
665
|
/>
|
|
657
666
|
)
|
|
658
667
|
})
|
|
@@ -692,41 +701,6 @@ export const AnimatedSidebarClose = forwardRef<
|
|
|
692
701
|
)
|
|
693
702
|
})
|
|
694
703
|
|
|
695
|
-
export interface AnimatedSidebarRailProps extends ButtonHTMLAttributes<HTMLButtonElement> {}
|
|
696
|
-
|
|
697
|
-
export const AnimatedSidebarRail = forwardRef<
|
|
698
|
-
HTMLButtonElement,
|
|
699
|
-
AnimatedSidebarRailProps
|
|
700
|
-
>(function AnimatedSidebarRail(
|
|
701
|
-
{ className, onClick, type = "button", ...props },
|
|
702
|
-
forwardedRef
|
|
703
|
-
) {
|
|
704
|
-
const context = useAnimatedSidebar()
|
|
705
|
-
const panel = useAnimatedSidebarPanel()
|
|
706
|
-
|
|
707
|
-
return (
|
|
708
|
-
<button
|
|
709
|
-
{...props}
|
|
710
|
-
ref={forwardedRef}
|
|
711
|
-
type={type}
|
|
712
|
-
data-side={panel.side}
|
|
713
|
-
aria-label={props["aria-label"] ?? "Toggle sidebar"}
|
|
714
|
-
title="Toggle sidebar"
|
|
715
|
-
tabIndex={-1}
|
|
716
|
-
onClick={(event) => {
|
|
717
|
-
onClick?.(event)
|
|
718
|
-
if (event.defaultPrevented) return
|
|
719
|
-
context.toggleSidebar(panel.side)
|
|
720
|
-
}}
|
|
721
|
-
className={cn(
|
|
722
|
-
"absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 outline-none md:block",
|
|
723
|
-
"after:absolute after:inset-y-0 after:left-1/2 after:w-px after:bg-transparent after:transition-colors hover:after:bg-border",
|
|
724
|
-
"data-[side=left]:left-full data-[side=right]:right-0 data-[side=right]:translate-x-1/2",
|
|
725
|
-
className
|
|
726
|
-
)}
|
|
727
|
-
/>
|
|
728
|
-
)
|
|
729
|
-
})
|
|
730
704
|
|
|
731
705
|
export interface AnimatedSidebarInsetProps extends HTMLMotionProps<"main"> {}
|
|
732
706
|
|
|
@@ -740,8 +714,9 @@ export const AnimatedSidebarInset = forwardRef<
|
|
|
740
714
|
ref={forwardedRef}
|
|
741
715
|
data-slot="sidebar-inset"
|
|
742
716
|
className={cn(
|
|
743
|
-
"relative flex min-w-0 flex-1 flex-col bg-
|
|
744
|
-
"
|
|
717
|
+
"relative flex min-w-0 flex-1 flex-col bg-neutral-50 dark:bg-neutral-900",
|
|
718
|
+
"outline-offset-0.5 overflow-hidden border-t-3 border-white outline-neutral-100 dark:border-neutral-800 dark:inset-ring-black",
|
|
719
|
+
"m-2 mx-0 rounded-lg shadow-md shadow-neutral-200 dark:shadow-neutral-950",
|
|
745
720
|
className
|
|
746
721
|
)}
|
|
747
722
|
/>
|
|
@@ -46,10 +46,10 @@ export const buttonVariants = cva(
|
|
|
46
46
|
size: {
|
|
47
47
|
default: "h-9 px-[calc(--spacing(3)-1px)] sm:h-8",
|
|
48
48
|
icon: "size-9 sm:size-8",
|
|
49
|
-
"icon-lg": "size-
|
|
50
|
-
"icon-sm": "size-
|
|
49
|
+
"icon-lg": "size-8 sm:size-8",
|
|
50
|
+
"icon-sm": "size-7 sm:size-6",
|
|
51
51
|
"icon-xl":
|
|
52
|
-
"size-
|
|
52
|
+
"size-10 sm:size-9 [&_svg:not([class*='size-'])]:size-5 sm:[&_svg:not([class*='size-'])]:size-4.5",
|
|
53
53
|
"icon-xs":
|
|
54
54
|
"size-7 rounded-md before:rounded-[calc(var(--radius-md)-1px)] sm:size-6 not-in-data-[slot=input-group]:[&_svg:not([class*='size-'])]:size-4 sm:not-in-data-[slot=input-group]:[&_svg:not([class*='size-'])]:size-3.5",
|
|
55
55
|
lg: "h-10 px-[calc(--spacing(3.5)-1px)] sm:h-9",
|