@exegia/corpora-ui 0.17.0 → 0.19.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/nav/sidebar-block.d.ts +1 -1
- package/dist-lib/components/blocks/scaffold/__tests__/scaffold.test.d.ts +1 -0
- package/dist-lib/components/blocks/scaffold/constants.d.ts +23 -0
- package/dist-lib/components/blocks/scaffold/index.d.ts +27 -0
- package/dist-lib/components/blocks/scaffold/panel-close-button.d.ts +4 -0
- package/dist-lib/components/blocks/scaffold/panel-menu-button.d.ts +8 -0
- package/dist-lib/components/blocks/scaffold/scaffold-actions.d.ts +10 -0
- package/dist-lib/components/blocks/scaffold/scaffold-canvas.d.ts +7 -0
- package/dist-lib/components/blocks/scaffold/scaffold-context.d.ts +5 -0
- package/dist-lib/components/blocks/scaffold/scaffold-inspector.d.ts +9 -0
- package/dist-lib/components/blocks/scaffold/scaffold-main.d.ts +8 -0
- package/dist-lib/components/blocks/scaffold/scaffold-panel.d.ts +10 -0
- package/dist-lib/components/blocks/scaffold/scaffold-root.d.ts +8 -0
- package/dist-lib/components/blocks/scaffold/scaffold-sidebar.d.ts +7 -0
- package/dist-lib/components/blocks/scaffold/scaffold-sub-panel.d.ts +3 -0
- package/dist-lib/components/blocks/scaffold/scaffold-tab.d.ts +9 -0
- package/dist-lib/components/blocks/scaffold/type.d.ts +135 -0
- package/dist-lib/components/blocks/scaffold/use-scaffold.d.ts +8 -0
- package/dist-lib/components/blocks/scaffold/utils.d.ts +21 -0
- package/dist-lib/components/blocks/shell/animated-panel-inset.d.ts +2 -0
- package/dist-lib/components/blocks/shell/animated-panel-provider.d.ts +2 -0
- package/dist-lib/components/blocks/shell/animated-panel-trigger.d.ts +2 -0
- package/dist-lib/components/blocks/shell/animated-panel.d.ts +2 -0
- package/dist-lib/components/blocks/shell/animated-sidebar-content.d.ts +2 -0
- package/dist-lib/components/blocks/shell/animated-sidebar-footer.d.ts +2 -0
- package/dist-lib/components/blocks/shell/animated-sidebar-group-content.d.ts +2 -0
- package/dist-lib/components/blocks/shell/animated-sidebar-group-label.d.ts +2 -0
- package/dist-lib/components/blocks/shell/animated-sidebar-group.d.ts +2 -0
- package/dist-lib/components/blocks/shell/animated-sidebar-header.d.ts +2 -0
- package/dist-lib/components/blocks/shell/animated-sidebar-menu-button.d.ts +3 -0
- package/dist-lib/components/blocks/shell/animated-sidebar-menu-item.d.ts +2 -0
- package/dist-lib/components/blocks/shell/animated-sidebar-menu-sub-button.d.ts +3 -0
- package/dist-lib/components/blocks/shell/animated-sidebar-menu-sub-item.d.ts +2 -0
- package/dist-lib/components/blocks/shell/animated-sidebar-menu-sub.d.ts +2 -0
- package/dist-lib/components/blocks/shell/animated-sidebar-menu.d.ts +2 -0
- package/dist-lib/components/blocks/shell/index.d.ts +16 -0
- package/dist-lib/components/blocks/shell/type.d.ts +90 -4
- package/dist-lib/components/blocks/shell/utils.d.ts +37 -0
- package/dist-lib/components/motion/index.d.ts +1 -0
- package/dist-lib/components/motion/overflow-actions.d.ts +35 -0
- package/dist-lib/components/ui/button-group.d.ts +11 -0
- package/dist-lib/components/ui/glasscn/glass-button-group.d.ts +5 -0
- package/dist-lib/components/ui/glasscn/glass-container.d.ts +7 -0
- package/dist-lib/components/ui/glasscn/glass-separator.d.ts +5 -0
- package/dist-lib/components/ui/group.d.ts +17 -0
- package/dist-lib/components/ui/separator.d.ts +2 -3
- package/dist-lib/components/ui/sheet.d.ts +14 -0
- package/dist-lib/components/ui/tooltip.d.ts +6 -0
- package/dist-lib/index.d.ts +2 -1
- package/dist-lib/index.js +1631 -1101
- package/dist-lib/index.js.map +1 -1
- package/dist-lib/lib/ease.d.ts +3 -0
- package/dist-lib/lib/hooks/use-hover-capable.d.ts +6 -0
- package/package.json +2 -1
- package/src/components/beste/piece/browser-frame.tsx +2 -2
- package/src/components/blocks/nav/sidebar-block.tsx +5 -5
- package/src/components/blocks/nav/sidebar-nav-row.tsx +4 -5
- package/src/components/blocks/scaffold/__tests__/scaffold.test.tsx +286 -0
- package/src/components/blocks/scaffold/constants.ts +32 -0
- package/src/components/blocks/scaffold/index.ts +41 -0
- package/src/components/blocks/scaffold/panel-close-button.tsx +36 -0
- package/src/components/blocks/scaffold/panel-menu-button.tsx +218 -0
- package/src/components/blocks/scaffold/scaffold-actions.tsx +88 -0
- package/src/components/blocks/scaffold/scaffold-canvas.tsx +29 -0
- package/src/components/blocks/scaffold/scaffold-context.ts +18 -0
- package/src/components/blocks/scaffold/scaffold-inspector.tsx +80 -0
- package/src/components/blocks/scaffold/scaffold-main.tsx +28 -0
- package/src/components/blocks/scaffold/scaffold-panel.tsx +88 -0
- package/src/components/blocks/scaffold/scaffold-root.tsx +68 -0
- package/src/components/blocks/scaffold/scaffold-sidebar.tsx +31 -0
- package/src/components/blocks/scaffold/scaffold-sub-panel.tsx +51 -0
- package/src/components/blocks/scaffold/scaffold-tab.tsx +66 -0
- package/src/components/blocks/scaffold/type.ts +172 -0
- package/src/components/blocks/scaffold/use-scaffold.ts +48 -0
- package/src/components/blocks/scaffold/utils.ts +46 -0
- package/src/components/blocks/shell/animated-panel-inset.tsx +23 -0
- package/src/components/blocks/shell/animated-panel-provider.tsx +155 -0
- package/src/components/blocks/shell/animated-panel-trigger.tsx +42 -0
- package/src/components/blocks/shell/animated-panel.tsx +135 -0
- package/src/components/blocks/shell/animated-sidebar-content.tsx +19 -0
- package/src/components/blocks/shell/animated-sidebar-footer.tsx +19 -0
- package/src/components/blocks/shell/animated-sidebar-group-content.tsx +16 -0
- package/src/components/blocks/shell/animated-sidebar-group-label.tsx +29 -0
- package/src/components/blocks/shell/animated-sidebar-group.tsx +16 -0
- package/src/components/blocks/shell/animated-sidebar-header.tsx +16 -0
- package/src/components/blocks/shell/animated-sidebar-menu-button.tsx +151 -0
- package/src/components/blocks/shell/animated-sidebar-menu-item.tsx +20 -0
- package/src/components/blocks/shell/animated-sidebar-menu-sub-button.tsx +85 -0
- package/src/components/blocks/shell/animated-sidebar-menu-sub-item.tsx +19 -0
- package/src/components/blocks/shell/animated-sidebar-menu-sub.tsx +44 -0
- package/src/components/blocks/shell/animated-sidebar-menu.tsx +26 -0
- package/src/components/blocks/shell/index.ts +18 -0
- package/src/components/blocks/shell/shell-layout.tsx +28 -36
- package/src/components/blocks/shell/type.ts +112 -6
- package/src/components/blocks/shell/use-shell-panels.ts +1 -1
- package/src/components/blocks/shell/utils.ts +142 -1
- package/src/components/docs/demo-controls.tsx +1 -1
- package/src/components/motion/index.ts +0 -0
- package/src/components/motion/overflow-actions.tsx +376 -0
- package/src/components/ui/button-group.tsx +88 -0
- package/src/components/ui/glasscn/glass-button-group.tsx +48 -0
- package/src/components/ui/glasscn/glass-container.tsx +125 -0
- package/src/components/ui/glasscn/glass-separator.tsx +39 -0
- package/src/components/ui/glasscn/liquid-glass.tsx +250 -210
- package/src/components/ui/group.tsx +92 -0
- package/src/components/ui/separator.tsx +11 -11
- package/src/components/ui/sheet.tsx +135 -0
- package/src/components/ui/tooltip.tsx +66 -0
- package/src/index.css +1 -1
- package/src/index.ts +13 -1
- package/src/lib/ease.ts +26 -0
- package/src/lib/hooks/use-hover-capable.ts +23 -0
- package/dist-lib/components/motion/animated-sidebar.d.ts +0 -106
- package/src/components/motion/animated-sidebar.tsx +0 -1171
|
@@ -4,15 +4,15 @@ import { MotionIcon } from "motion-icons-react"
|
|
|
4
4
|
import * as React from "react"
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
AnimatedSidebarProvider,
|
|
10
|
-
AnimatedSidebarTrigger,
|
|
11
|
-
} from "@/components/motion/animated-sidebar"
|
|
7
|
+
AnimatedPanel
|
|
8
|
+
} from "./animated-panel.tsx"
|
|
12
9
|
import { cn } from "@/lib/utils"
|
|
13
10
|
import type { ShellLayoutProps, ShellPanelControlProps } from "./type"
|
|
14
11
|
import { TITLE_BAR_HEIGHT } from "./utils"
|
|
15
12
|
import type { ClassNameValue } from "tailwind-merge"
|
|
13
|
+
import { AnimatedPanelProvider } from "./animated-panel-provider.tsx"
|
|
14
|
+
import { AnimatedPanelTrigger } from "./animated-panel-trigger.tsx"
|
|
15
|
+
import { AnimatedPanelInset } from "./animated-panel-inset.tsx"
|
|
16
16
|
|
|
17
17
|
export function ShellLayout({
|
|
18
18
|
children,
|
|
@@ -41,56 +41,56 @@ export function ShellLayout({
|
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
return (
|
|
44
|
-
<
|
|
44
|
+
<AnimatedPanelProvider
|
|
45
45
|
{...panelControlProps}
|
|
46
46
|
defaultOpen={initialOpen}
|
|
47
|
-
className={cn(
|
|
48
|
-
"relative block-full pr-2",
|
|
49
|
-
className,
|
|
50
|
-
background
|
|
51
|
-
)}
|
|
47
|
+
className={cn("relative h-full min-h-0 pb-2", className, background)}
|
|
52
48
|
style={{
|
|
53
49
|
paddingTop: variant === "desktop" ? TITLE_BAR_HEIGHT : 0,
|
|
54
50
|
}}
|
|
55
51
|
>
|
|
56
|
-
<
|
|
52
|
+
<AnimatedPanel
|
|
57
53
|
ariaLabel="Primary navigation"
|
|
58
54
|
collapsible="icon"
|
|
59
55
|
role="navigation"
|
|
60
56
|
variant="inset"
|
|
61
57
|
>
|
|
62
58
|
{panels?.left?.component}
|
|
63
|
-
</
|
|
59
|
+
</AnimatedPanel>
|
|
64
60
|
|
|
65
|
-
<
|
|
66
|
-
<header className="flex h-12 items-center justify-between gap-2 px-2">
|
|
61
|
+
<AnimatedPanelInset className="min-w-24">
|
|
62
|
+
<header className="flex h-12 items-center justify-between gap-2 border-b px-2">
|
|
67
63
|
<div className="flex min-w-0 items-center gap-2">
|
|
68
|
-
<
|
|
64
|
+
<AnimatedPanelTrigger>
|
|
69
65
|
{panels?.left?.trigger ?? (
|
|
70
66
|
<MotionIcon name="PanelLeft" size={24} animation="press" />
|
|
71
67
|
)}
|
|
72
|
-
</
|
|
68
|
+
</AnimatedPanelTrigger>
|
|
73
69
|
</div>
|
|
74
70
|
{header && <div className="flex flex-1 items-center">{header}</div>}
|
|
75
71
|
<div className="flex shrink-0 items-center gap-2">
|
|
76
|
-
<
|
|
72
|
+
<AnimatedPanelTrigger aria-label="Toggle panel" side="right">
|
|
77
73
|
{panels?.right?.trigger ?? (
|
|
78
|
-
<MotionIcon
|
|
74
|
+
<MotionIcon
|
|
75
|
+
className="opacity-70"
|
|
76
|
+
name="PanelRight"
|
|
77
|
+
size={24}
|
|
78
|
+
/>
|
|
79
79
|
)}
|
|
80
|
-
</
|
|
80
|
+
</AnimatedPanelTrigger>
|
|
81
81
|
</div>
|
|
82
82
|
</header>
|
|
83
|
-
<div className="min-h-24 flex-1 overflow-auto">
|
|
84
|
-
|
|
85
|
-
</div>
|
|
86
|
-
</AnimatedSidebarInset>
|
|
83
|
+
<div className="min-h-24 flex-1 overflow-auto">{children}</div>
|
|
84
|
+
</AnimatedPanelInset>
|
|
87
85
|
|
|
88
|
-
<
|
|
86
|
+
<AnimatedPanel
|
|
89
87
|
ariaLabel={panels?.right?.name ?? "Secondary panel"}
|
|
90
88
|
// Below md the panel is portal led over the page, so it carries the
|
|
91
89
|
// surface itself; the desktop rail keeps it on the inner panel.
|
|
92
90
|
className={cn(
|
|
93
|
-
"
|
|
91
|
+
"mr-2 bg-neutral-50 dark:border-neutral-800 dark:bg-neutral-900",
|
|
92
|
+
"outline-offset-0.5 border-t-3 border-white outline-neutral-100 dark:inset-ring-black",
|
|
93
|
+
"rounded-lg shadow-md shadow-neutral-200 dark:shadow-neutral-950"
|
|
94
94
|
)}
|
|
95
95
|
collapsible="offcanvas"
|
|
96
96
|
role="complementary"
|
|
@@ -98,15 +98,7 @@ export function ShellLayout({
|
|
|
98
98
|
variant="inset"
|
|
99
99
|
>
|
|
100
100
|
{panels?.right?.component}
|
|
101
|
-
</
|
|
102
|
-
</
|
|
103
|
-
)
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
function ShellLayoutPlaceholder() {
|
|
107
|
-
return (
|
|
108
|
-
<div className="flex flex-col flex-1 p-4">
|
|
109
|
-
<div className="h-96 border border-border bg-muted-foreground/10 rounded-lg" />
|
|
110
|
-
</div>
|
|
101
|
+
</AnimatedPanel>
|
|
102
|
+
</AnimatedPanelProvider>
|
|
111
103
|
)
|
|
112
104
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { ReactNode } from "react"
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
import {
|
|
4
|
+
type ButtonHTMLAttributes,
|
|
5
|
+
type CSSProperties,
|
|
6
|
+
type HTMLAttributes,
|
|
7
|
+
} from "react"
|
|
8
|
+
import type { HTMLMotionProps } from "motion/react"
|
|
7
9
|
|
|
8
10
|
export interface ShellAction {
|
|
9
11
|
id: string
|
|
@@ -47,7 +49,7 @@ export type TPanelMap<Side extends TPanelSide = TPanelSide> = Partial<
|
|
|
47
49
|
>
|
|
48
50
|
|
|
49
51
|
/** The open/close surface of the shell's panels, lifted straight from
|
|
50
|
-
*
|
|
52
|
+
* AnimatedPanelProvider — every prop is keyed by side, there are no
|
|
51
53
|
* explicit per-side props. `useShellPanels` produces the controlled subset
|
|
52
54
|
* of these as `providerProps`. */
|
|
53
55
|
export type ShellPanelControlProps = Pick<
|
|
@@ -82,7 +84,7 @@ export interface ShellPanelControls {
|
|
|
82
84
|
/** Desktop-only convenience — the in-shell triggers already pick the
|
|
83
85
|
* mobile state themselves when the viewport is narrow. */
|
|
84
86
|
toggle: (side: SidebarSide) => void
|
|
85
|
-
/** Spread onto ShellLayout (or
|
|
87
|
+
/** Spread onto ShellLayout (or AnimatedPanelProvider directly). */
|
|
86
88
|
providerProps: ShellPanelControlProps
|
|
87
89
|
}
|
|
88
90
|
|
|
@@ -95,3 +97,107 @@ export interface ShellLayoutProps extends ShellPanelControlProps {
|
|
|
95
97
|
className?: string
|
|
96
98
|
variant?: "web" | "desktop"
|
|
97
99
|
}
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
export type SidebarSide = "left" | "right"
|
|
103
|
+
/** Open flags keyed by the side. Sides left out stay uncontrolled / at their
|
|
104
|
+
* default — there is no per-side prop, the record IS the API. */
|
|
105
|
+
export type SidebarOpenState = Partial<Record<SidebarSide, boolean>>
|
|
106
|
+
export type SidebarVariant = "sidebar" | "floating" | "inset"
|
|
107
|
+
export type SidebarCollapsible = "offcanvas" | "icon" | "none"
|
|
108
|
+
|
|
109
|
+
export interface AnimatedSidebarContextValue {
|
|
110
|
+
isMobile: boolean
|
|
111
|
+
layoutId: string
|
|
112
|
+
/** Desktop open state, keyed by side. */
|
|
113
|
+
open: Record<SidebarSide, boolean>
|
|
114
|
+
/** Mobile overlay open state, keyed by side. */
|
|
115
|
+
openMobile: Record<SidebarSide, boolean>
|
|
116
|
+
reduce: boolean
|
|
117
|
+
setOpen: (open: boolean, side: SidebarSide) => void
|
|
118
|
+
setOpenMobile: (open: boolean, side: SidebarSide) => void
|
|
119
|
+
/** Mobile-aware: toggles the overlay below md, the docked panel above. */
|
|
120
|
+
toggleSidebar: (side: SidebarSide) => void
|
|
121
|
+
triggerRefs: Record<SidebarSide, React.RefObject<HTMLButtonElement | null>>
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface AnimatedSidebarProviderProps extends HTMLAttributes<HTMLDivElement> {
|
|
125
|
+
/** Controlled desktop open state, keyed by the side. A side left undefined
|
|
126
|
+
* stays uncontrolled. */
|
|
127
|
+
open?: SidebarOpenState
|
|
128
|
+
/** Initial desktop open state, merged over `{ left: true, right: false }`. */
|
|
129
|
+
defaultOpen?: SidebarOpenState
|
|
130
|
+
onOpenChange?: (open: boolean, side: SidebarSide) => void
|
|
131
|
+
/** Controlled mobile overlay state, keyed by side. */
|
|
132
|
+
openMobile?: SidebarOpenState
|
|
133
|
+
/** Initial mobile overlay state — every side starts closed. */
|
|
134
|
+
defaultOpenMobile?: SidebarOpenState
|
|
135
|
+
onOpenMobileChange?: (open: boolean, side: SidebarSide) => void
|
|
136
|
+
style?: SidebarProviderStyle
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export type SidebarProviderStyle = CSSProperties & {
|
|
140
|
+
"--sidebar-width"?: string
|
|
141
|
+
"--sidebar-width-icon"?: string
|
|
142
|
+
"--sidebar-width-mobile"?: string
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export type AnimatedSidebarInsetProps = HTMLMotionProps<"main">
|
|
146
|
+
|
|
147
|
+
export interface AnimatedSidebarTriggerProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
148
|
+
side?: SidebarSide
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export interface AnimatedSidebarPanelContextValue {
|
|
152
|
+
collapsed: boolean
|
|
153
|
+
collapsible: SidebarCollapsible
|
|
154
|
+
side: SidebarSide
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export interface AnimatedSidebarProps extends Omit<
|
|
158
|
+
HTMLMotionProps<"aside">,
|
|
159
|
+
"children"
|
|
160
|
+
> {
|
|
161
|
+
children?: ReactNode
|
|
162
|
+
side?: SidebarSide
|
|
163
|
+
variant?: SidebarVariant
|
|
164
|
+
collapsible?: SidebarCollapsible
|
|
165
|
+
ariaLabel?: string
|
|
166
|
+
panelClassName?: string
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export interface AnimatedSidebarMenuSubProps extends Omit<
|
|
170
|
+
HTMLMotionProps<"ul">,
|
|
171
|
+
"children"
|
|
172
|
+
> {
|
|
173
|
+
open: boolean
|
|
174
|
+
children?: ReactNode
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export interface AnimatedSidebarMenuSubButtonProps {
|
|
178
|
+
children: ReactNode
|
|
179
|
+
icon?: ReactNode
|
|
180
|
+
href?: string
|
|
181
|
+
isActive?: boolean
|
|
182
|
+
disabled?: boolean
|
|
183
|
+
closeOnSelect?: boolean
|
|
184
|
+
target?: "_blank" | "_self" | "_parent" | "_top"
|
|
185
|
+
rel?: string
|
|
186
|
+
onSelect?: () => void
|
|
187
|
+
className?: string
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export interface AnimatedSidebarMenuButtonProps {
|
|
191
|
+
children: ReactNode
|
|
192
|
+
icon?: ReactNode
|
|
193
|
+
badge?: ReactNode
|
|
194
|
+
href?: string
|
|
195
|
+
isActive?: boolean
|
|
196
|
+
ariaExpanded?: boolean
|
|
197
|
+
disabled?: boolean
|
|
198
|
+
closeOnSelect?: boolean
|
|
199
|
+
target?: "_blank" | "_self" | "_parent" | "_top"
|
|
200
|
+
rel?: string
|
|
201
|
+
onSelect?: () => void
|
|
202
|
+
className?: string
|
|
203
|
+
}
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
import { useCallback, useMemo, useState } from "react"
|
|
4
4
|
|
|
5
|
-
import type { SidebarSide } from "@/components/motion/animated-sidebar"
|
|
6
5
|
import type {
|
|
7
6
|
ShellPanelControlProps,
|
|
8
7
|
ShellPanelControls,
|
|
8
|
+
SidebarSide,
|
|
9
9
|
UseShellPanelsOptions,
|
|
10
10
|
} from "./type"
|
|
11
11
|
|
|
@@ -1,2 +1,143 @@
|
|
|
1
|
-
|
|
2
1
|
export const TITLE_BAR_HEIGHT = 48
|
|
2
|
+
// The desktop rail settles at a hard zero-width boundary. Keep the spring
|
|
3
|
+
// critically damped so it cannot overshoot, pause against that boundary, and
|
|
4
|
+
// then snap back during the final frame.
|
|
5
|
+
import { EASE_OUT, EASE_DRAWER } from "@/lib/ease.ts"
|
|
6
|
+
import type { Variants } from "motion/react"
|
|
7
|
+
import { createContext, useContext, useSyncExternalStore } from "react"
|
|
8
|
+
import type {
|
|
9
|
+
AnimatedSidebarContextValue,
|
|
10
|
+
AnimatedSidebarPanelContextValue,
|
|
11
|
+
} from "./type"
|
|
12
|
+
|
|
13
|
+
export const SIDEBAR_MORPH_TRANSITION = {
|
|
14
|
+
type: "spring",
|
|
15
|
+
stiffness: 380,
|
|
16
|
+
damping: 35,
|
|
17
|
+
mass: 0.75,
|
|
18
|
+
} as const
|
|
19
|
+
|
|
20
|
+
export const LABEL_ENTER_TRANSITION = {
|
|
21
|
+
duration: 0.2,
|
|
22
|
+
delay: 0.08,
|
|
23
|
+
ease: EASE_OUT,
|
|
24
|
+
} as const
|
|
25
|
+
|
|
26
|
+
export const LABEL_EXIT_TRANSITION = {
|
|
27
|
+
duration: 0.12,
|
|
28
|
+
ease: EASE_OUT,
|
|
29
|
+
} as const
|
|
30
|
+
|
|
31
|
+
export const PANEL_TRANSITION = {
|
|
32
|
+
duration: 0.36,
|
|
33
|
+
ease: EASE_DRAWER,
|
|
34
|
+
} as const
|
|
35
|
+
|
|
36
|
+
export const REDUCED_TRANSITION = {
|
|
37
|
+
duration: 0.16,
|
|
38
|
+
ease: EASE_OUT,
|
|
39
|
+
} as const
|
|
40
|
+
|
|
41
|
+
const SUBMENU_TRANSITION = {
|
|
42
|
+
duration: 0.18,
|
|
43
|
+
ease: EASE_OUT,
|
|
44
|
+
} as const
|
|
45
|
+
|
|
46
|
+
export const SUBMENU_VARIANTS: Variants = {
|
|
47
|
+
closed: {
|
|
48
|
+
opacity: 0,
|
|
49
|
+
clipPath: "inset(0 0 100% 0 round 8px)",
|
|
50
|
+
transition: {
|
|
51
|
+
duration: 0.14,
|
|
52
|
+
ease: EASE_OUT,
|
|
53
|
+
staggerChildren: 0.025,
|
|
54
|
+
staggerDirection: -1,
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
open: {
|
|
58
|
+
opacity: 1,
|
|
59
|
+
clipPath: "inset(0 0 0% 0 round 8px)",
|
|
60
|
+
transition: {
|
|
61
|
+
duration: 0.2,
|
|
62
|
+
delayChildren: 0.035,
|
|
63
|
+
ease: EASE_OUT,
|
|
64
|
+
staggerChildren: 0.045,
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export const SUBMENU_ITEM_VARIANTS: Variants = {
|
|
70
|
+
closed: {
|
|
71
|
+
opacity: 0,
|
|
72
|
+
y: -6,
|
|
73
|
+
filter: "blur(3px)",
|
|
74
|
+
},
|
|
75
|
+
open: {
|
|
76
|
+
opacity: 1,
|
|
77
|
+
y: 0,
|
|
78
|
+
filter: "blur(0px)",
|
|
79
|
+
transition: SUBMENU_TRANSITION,
|
|
80
|
+
},
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export const FOCUSABLE_SELECTOR = [
|
|
84
|
+
"a[href]",
|
|
85
|
+
"button:not([disabled])",
|
|
86
|
+
"input:not([disabled])",
|
|
87
|
+
"select:not([disabled])",
|
|
88
|
+
"textarea:not([disabled])",
|
|
89
|
+
"[tabindex]:not([tabindex='-1'])",
|
|
90
|
+
].join(",")
|
|
91
|
+
|
|
92
|
+
export const MOBILE_QUERY = "(max-width: 767px)"
|
|
93
|
+
export const SIDEBAR_KEYBOARD_SHORTCUT = "b"
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
export const AnimatedSidebarContext =
|
|
97
|
+
createContext<AnimatedSidebarContextValue | null>(null)
|
|
98
|
+
|
|
99
|
+
export const AnimatedSidebarPanelContext =
|
|
100
|
+
createContext<AnimatedSidebarPanelContextValue | null>(null)
|
|
101
|
+
|
|
102
|
+
export function useAnimatedSidebar() {
|
|
103
|
+
const context = useContext(AnimatedSidebarContext)
|
|
104
|
+
if (!context) {
|
|
105
|
+
throw new Error(
|
|
106
|
+
"useAnimatedSidebar must be used inside AnimatedPanelProvider."
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
return context
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function subscribeToMobileQuery(callback: () => void) {
|
|
113
|
+
const query = window.matchMedia(MOBILE_QUERY)
|
|
114
|
+
query.addEventListener("change", callback)
|
|
115
|
+
return () => query.removeEventListener("change", callback)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function getMobileSnapshot() {
|
|
119
|
+
return window.matchMedia(MOBILE_QUERY).matches
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export function getServerMobileSnapshot() {
|
|
123
|
+
return false
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function useIsMobile() {
|
|
127
|
+
return useSyncExternalStore(
|
|
128
|
+
subscribeToMobileQuery,
|
|
129
|
+
getMobileSnapshot,
|
|
130
|
+
getServerMobileSnapshot
|
|
131
|
+
)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
export function useAnimatedSidebarPanel() {
|
|
136
|
+
const context = useContext(AnimatedSidebarPanelContext)
|
|
137
|
+
if (!context) {
|
|
138
|
+
throw new Error(
|
|
139
|
+
"Animated Sidebar parts must be used inside AnimatedPanel."
|
|
140
|
+
)
|
|
141
|
+
}
|
|
142
|
+
return context
|
|
143
|
+
}
|
|
File without changes
|