beads-kanban-ui 0.1.0 → 0.1.1
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/README.md +16 -222
- package/package.json +18 -55
- package/.designs/beads-kanban-ui-bj0.md +0 -73
- package/.designs/beads-kanban-ui-qxq.md +0 -144
- package/.designs/epic-support.md +0 -282
- package/.env.local.example +0 -2
- package/.eslintrc.json +0 -3
- package/.gitattributes +0 -3
- package/.github/workflows/release.yml +0 -123
- package/.history/README_20260121193710.md +0 -227
- package/.history/README_20260121193918.md +0 -227
- package/.history/README_20260121193921.md +0 -227
- package/.history/README_20260121193933.md +0 -227
- package/.history/README_20260121193934.md +0 -227
- package/.history/README_20260121193944.md +0 -227
- package/.history/README_20260121193953.md +0 -227
- package/.history/src/app/page_20260121133429.tsx +0 -134
- package/.history/src/app/page_20260121133928.tsx +0 -134
- package/.history/src/app/page_20260121144850.tsx +0 -138
- package/.history/src/app/page_20260121144854.tsx +0 -138
- package/.history/src/app/page_20260121144858.tsx +0 -138
- package/.history/src/app/page_20260121144902.tsx +0 -138
- package/.history/src/app/page_20260121144906.tsx +0 -138
- package/.history/src/app/page_20260121144911.tsx +0 -138
- package/.history/src/app/page_20260121144928.tsx +0 -138
- package/.playwright-mcp/.playwright-mcp/morphing-dialog-wheel-scroll-fix.png +0 -0
- package/.playwright-mcp/beams-test.png +0 -0
- package/.playwright-mcp/card-verification.png +0 -0
- package/.playwright-mcp/design-doc-dialog-fix-verification.png +0 -0
- package/.playwright-mcp/dialog-width-test.png +0 -0
- package/.playwright-mcp/homepage.png +0 -0
- package/.playwright-mcp/morphing-dialog-expanded.png +0 -0
- package/.playwright-mcp/morphing-dialog-fixes-final.png +0 -0
- package/.playwright-mcp/morphing-dialog-open.png +0 -0
- package/.playwright-mcp/page-2026-01-21T14-08-31-529Z.png +0 -0
- package/.playwright-mcp/page-2026-01-21T14-09-23-431Z.png +0 -0
- package/.playwright-mcp/page-2026-01-21T14-10-28-773Z.png +0 -0
- package/.playwright-mcp/page-2026-01-21T14-10-47-432Z.png +0 -0
- package/.playwright-mcp/page-2026-01-21T14-11-12-350Z.png +0 -0
- package/.playwright-mcp/screenshot-after-click.png +0 -0
- package/.playwright-mcp/screenshot-after-dialog-click.png +0 -0
- package/.playwright-mcp/sheet-restored-after-dialog-close.png +0 -0
- package/.playwright-mcp/test-1-sheet-open-with-overlay.png +0 -0
- package/.playwright-mcp/test-2-morphing-dialog-with-overlay.png +0 -0
- package/.playwright-mcp/test-3-sheet-open-dark-overlay.png +0 -0
- package/.playwright-mcp/test-4-morphing-dialog-with-dark-overlay.png +0 -0
- package/.playwright-mcp/test-5-morphing-dialog-scrolled.png +0 -0
- package/.playwright-mcp/test-6-sheet-restored-after-dialog-close.png +0 -0
- package/.playwright-mcp/wheel-scroll-fixed.png +0 -0
- package/Screenshots/bead-detail.png +0 -0
- package/Screenshots/dashboard.png +0 -0
- package/Screenshots/kanban-board.png +0 -0
- package/components.json +0 -27
- package/logo/logo.svg +0 -1
- package/next.config.js +0 -9
- package/npm/README.md +0 -37
- package/npm/package.json +0 -20
- package/postcss.config.js +0 -6
- package/public/logo.svg +0 -1
- package/restart.sh +0 -5
- package/server/Cargo.lock +0 -1685
- package/server/Cargo.toml +0 -24
- package/server/src/db.rs +0 -570
- package/server/src/main.rs +0 -141
- package/server/src/routes/beads.rs +0 -413
- package/server/src/routes/cli.rs +0 -150
- package/server/src/routes/fs.rs +0 -360
- package/server/src/routes/git.rs +0 -169
- package/server/src/routes/mod.rs +0 -107
- package/server/src/routes/projects.rs +0 -177
- package/server/src/routes/watch.rs +0 -211
- package/src/app/globals.css +0 -101
- package/src/app/layout.tsx +0 -36
- package/src/app/page.tsx +0 -348
- package/src/app/project/kanban-board.tsx +0 -356
- package/src/app/project/page.tsx +0 -18
- package/src/app/settings/page.tsx +0 -224
- package/src/components/Beams.css +0 -5
- package/src/components/Beams.jsx +0 -307
- package/src/components/Galaxy.css +0 -5
- package/src/components/Galaxy.jsx +0 -333
- package/src/components/activity-timeline.tsx +0 -172
- package/src/components/add-project-dialog.tsx +0 -219
- package/src/components/bead-card.tsx +0 -196
- package/src/components/bead-detail.tsx +0 -306
- package/src/components/color-picker.tsx +0 -101
- package/src/components/comment-input.tsx +0 -155
- package/src/components/comment-list.tsx +0 -147
- package/src/components/dependency-badge.tsx +0 -106
- package/src/components/design-doc-dialog.tsx +0 -58
- package/src/components/design-doc-preview.tsx +0 -97
- package/src/components/design-doc-viewer.tsx +0 -199
- package/src/components/editable-project-name.tsx +0 -178
- package/src/components/epic-card.tsx +0 -263
- package/src/components/folder-browser.tsx +0 -273
- package/src/components/footer.tsx +0 -27
- package/src/components/kanban/default.tsx +0 -184
- package/src/components/kanban-column.tsx +0 -167
- package/src/components/project-card.tsx +0 -191
- package/src/components/quick-filter-bar.tsx +0 -279
- package/src/components/scan-directory-dialog.tsx +0 -368
- package/src/components/status-donut.tsx +0 -197
- package/src/components/subtask-list.tsx +0 -128
- package/src/components/tag-picker.tsx +0 -252
- package/src/components/ui/.gitkeep +0 -0
- package/src/components/ui/alert-dialog.tsx +0 -141
- package/src/components/ui/avatar.tsx +0 -67
- package/src/components/ui/badge.tsx +0 -230
- package/src/components/ui/button.tsx +0 -433
- package/src/components/ui/card/index.tsx +0 -24
- package/src/components/ui/card/roiui-card.module.css +0 -197
- package/src/components/ui/card/roiui-card.tsx +0 -154
- package/src/components/ui/card/shadcn-card.tsx +0 -76
- package/src/components/ui/chart.tsx +0 -369
- package/src/components/ui/dialog.tsx +0 -122
- package/src/components/ui/dropdown-menu.tsx +0 -201
- package/src/components/ui/input.tsx +0 -22
- package/src/components/ui/kanban.tsx +0 -522
- package/src/components/ui/morphing-dialog.tsx +0 -457
- package/src/components/ui/popover.tsx +0 -33
- package/src/components/ui/progress.tsx +0 -28
- package/src/components/ui/scroll-area.tsx +0 -48
- package/src/components/ui/select.tsx +0 -159
- package/src/components/ui/separator.tsx +0 -31
- package/src/components/ui/sheet.tsx +0 -142
- package/src/components/ui/skeleton.tsx +0 -15
- package/src/components/ui/toast.tsx +0 -129
- package/src/components/ui/toaster.tsx +0 -35
- package/src/components/ui/tooltip.tsx +0 -30
- package/src/hooks/.gitkeep +0 -0
- package/src/hooks/use-bead-filters.ts +0 -261
- package/src/hooks/use-beads.ts +0 -162
- package/src/hooks/use-branch-statuses.ts +0 -161
- package/src/hooks/use-epics.ts +0 -173
- package/src/hooks/use-file-watcher.ts +0 -111
- package/src/hooks/use-keyboard-navigation.ts +0 -282
- package/src/hooks/use-project.ts +0 -61
- package/src/hooks/use-projects.ts +0 -93
- package/src/hooks/use-toast.ts +0 -194
- package/src/hooks/useClickOutside.tsx +0 -26
- package/src/lib/.gitkeep +0 -0
- package/src/lib/api.ts +0 -186
- package/src/lib/beads-parser.ts +0 -252
- package/src/lib/cli.ts +0 -193
- package/src/lib/db.ts +0 -145
- package/src/lib/design-doc.ts +0 -74
- package/src/lib/epic-parser.ts +0 -242
- package/src/lib/git.ts +0 -102
- package/src/lib/utils.ts +0 -12
- package/src/types/index.ts +0 -107
- package/tailwind.config.ts +0 -85
- package/tsconfig.json +0 -26
- /package/{npm/bin → bin}/cli.js +0 -0
- /package/{npm/scripts → scripts}/postinstall.js +0 -0
|
@@ -1,457 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import React, {
|
|
4
|
-
useCallback,
|
|
5
|
-
useContext,
|
|
6
|
-
useEffect,
|
|
7
|
-
useId,
|
|
8
|
-
useMemo,
|
|
9
|
-
useRef,
|
|
10
|
-
useState,
|
|
11
|
-
} from 'react';
|
|
12
|
-
import {
|
|
13
|
-
motion,
|
|
14
|
-
AnimatePresence,
|
|
15
|
-
MotionConfig,
|
|
16
|
-
Transition,
|
|
17
|
-
Variant,
|
|
18
|
-
} from 'motion/react';
|
|
19
|
-
import { createPortal } from 'react-dom';
|
|
20
|
-
import { RemoveScroll } from 'react-remove-scroll';
|
|
21
|
-
import { cn } from '@/lib/utils';
|
|
22
|
-
import { XIcon } from 'lucide-react';
|
|
23
|
-
import useClickOutside from '@/hooks/useClickOutside';
|
|
24
|
-
|
|
25
|
-
export type MorphingDialogContextType = {
|
|
26
|
-
isOpen: boolean;
|
|
27
|
-
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
|
28
|
-
uniqueId: string;
|
|
29
|
-
triggerRef: React.RefObject<HTMLButtonElement>;
|
|
30
|
-
contentRef: React.RefObject<HTMLDivElement>;
|
|
31
|
-
contentElement: HTMLDivElement | null;
|
|
32
|
-
setContentElement: React.Dispatch<React.SetStateAction<HTMLDivElement | null>>;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
const MorphingDialogContext =
|
|
36
|
-
React.createContext<MorphingDialogContextType | null>(null);
|
|
37
|
-
|
|
38
|
-
function useMorphingDialog() {
|
|
39
|
-
const context = useContext(MorphingDialogContext);
|
|
40
|
-
if (!context) {
|
|
41
|
-
throw new Error(
|
|
42
|
-
'useMorphingDialog must be used within a MorphingDialogProvider'
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
return context;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export type MorphingDialogProviderProps = {
|
|
49
|
-
children: React.ReactNode;
|
|
50
|
-
transition?: Transition;
|
|
51
|
-
onOpenChange?: (isOpen: boolean) => void;
|
|
52
|
-
defaultOpen?: boolean;
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
function MorphingDialogProvider({
|
|
56
|
-
children,
|
|
57
|
-
transition,
|
|
58
|
-
onOpenChange,
|
|
59
|
-
defaultOpen = false,
|
|
60
|
-
}: MorphingDialogProviderProps) {
|
|
61
|
-
const [isOpen, setIsOpen] = useState(defaultOpen);
|
|
62
|
-
const [contentElement, setContentElement] = useState<HTMLDivElement | null>(null);
|
|
63
|
-
const uniqueId = useId();
|
|
64
|
-
const triggerRef = useRef<HTMLButtonElement>(null!);
|
|
65
|
-
const contentRef = useRef<HTMLDivElement>(null!);
|
|
66
|
-
|
|
67
|
-
// Call onOpenChange callback when isOpen changes (after render)
|
|
68
|
-
useEffect(() => {
|
|
69
|
-
onOpenChange?.(isOpen);
|
|
70
|
-
}, [isOpen, onOpenChange]);
|
|
71
|
-
|
|
72
|
-
const contextValue = useMemo(
|
|
73
|
-
() => ({
|
|
74
|
-
isOpen,
|
|
75
|
-
setIsOpen,
|
|
76
|
-
uniqueId,
|
|
77
|
-
triggerRef,
|
|
78
|
-
contentRef,
|
|
79
|
-
contentElement,
|
|
80
|
-
setContentElement,
|
|
81
|
-
}),
|
|
82
|
-
[isOpen, contentElement]
|
|
83
|
-
);
|
|
84
|
-
|
|
85
|
-
return (
|
|
86
|
-
<MorphingDialogContext.Provider value={contextValue}>
|
|
87
|
-
<MotionConfig transition={transition}>{children}</MotionConfig>
|
|
88
|
-
</MorphingDialogContext.Provider>
|
|
89
|
-
);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export type MorphingDialogProps = {
|
|
93
|
-
children: React.ReactNode;
|
|
94
|
-
transition?: Transition;
|
|
95
|
-
onOpenChange?: (isOpen: boolean) => void;
|
|
96
|
-
defaultOpen?: boolean;
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
function MorphingDialog({ children, transition, onOpenChange, defaultOpen }: MorphingDialogProps) {
|
|
100
|
-
return (
|
|
101
|
-
<MorphingDialogProvider onOpenChange={onOpenChange} defaultOpen={defaultOpen}>
|
|
102
|
-
<MotionConfig transition={transition}>{children}</MotionConfig>
|
|
103
|
-
</MorphingDialogProvider>
|
|
104
|
-
);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export type MorphingDialogTriggerProps = {
|
|
108
|
-
children: React.ReactNode;
|
|
109
|
-
className?: string;
|
|
110
|
-
style?: React.CSSProperties;
|
|
111
|
-
triggerRef?: React.RefObject<HTMLButtonElement>;
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
function MorphingDialogTrigger({
|
|
115
|
-
children,
|
|
116
|
-
className,
|
|
117
|
-
style,
|
|
118
|
-
triggerRef,
|
|
119
|
-
}: MorphingDialogTriggerProps) {
|
|
120
|
-
const { setIsOpen, isOpen, uniqueId } = useMorphingDialog();
|
|
121
|
-
|
|
122
|
-
const handleClick = useCallback(() => {
|
|
123
|
-
setIsOpen(!isOpen);
|
|
124
|
-
}, [isOpen, setIsOpen]);
|
|
125
|
-
|
|
126
|
-
const handleKeyDown = useCallback(
|
|
127
|
-
(event: React.KeyboardEvent) => {
|
|
128
|
-
if (event.key === 'Enter' || event.key === ' ') {
|
|
129
|
-
event.preventDefault();
|
|
130
|
-
setIsOpen(!isOpen);
|
|
131
|
-
}
|
|
132
|
-
},
|
|
133
|
-
[isOpen, setIsOpen]
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
return (
|
|
137
|
-
<motion.button
|
|
138
|
-
ref={triggerRef}
|
|
139
|
-
layoutId={`dialog-${uniqueId}`}
|
|
140
|
-
className={cn('relative cursor-pointer', className)}
|
|
141
|
-
onClick={handleClick}
|
|
142
|
-
onKeyDown={handleKeyDown}
|
|
143
|
-
style={style}
|
|
144
|
-
aria-haspopup='dialog'
|
|
145
|
-
aria-expanded={isOpen}
|
|
146
|
-
aria-controls={`motion-ui-morphing-dialog-content-${uniqueId}`}
|
|
147
|
-
aria-label={`Open dialog ${uniqueId}`}
|
|
148
|
-
>
|
|
149
|
-
{children}
|
|
150
|
-
</motion.button>
|
|
151
|
-
);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
export type MorphingDialogContentProps = {
|
|
155
|
-
children: React.ReactNode;
|
|
156
|
-
className?: string;
|
|
157
|
-
style?: React.CSSProperties;
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
function MorphingDialogContent({
|
|
161
|
-
children,
|
|
162
|
-
className,
|
|
163
|
-
style,
|
|
164
|
-
}: MorphingDialogContentProps) {
|
|
165
|
-
const { setIsOpen, isOpen, uniqueId, triggerRef, contentRef, setContentElement } = useMorphingDialog();
|
|
166
|
-
// Use contentRef from context so RemoveScroll can allow scrolling inside this element
|
|
167
|
-
const containerRef = contentRef;
|
|
168
|
-
const [firstFocusableElement, setFirstFocusableElement] =
|
|
169
|
-
useState<HTMLElement | null>(null);
|
|
170
|
-
const [lastFocusableElement, setLastFocusableElement] =
|
|
171
|
-
useState<HTMLElement | null>(null);
|
|
172
|
-
|
|
173
|
-
// Register the content element for RemoveScroll shards
|
|
174
|
-
useEffect(() => {
|
|
175
|
-
if (containerRef.current) {
|
|
176
|
-
setContentElement(containerRef.current);
|
|
177
|
-
}
|
|
178
|
-
return () => {
|
|
179
|
-
setContentElement(null);
|
|
180
|
-
};
|
|
181
|
-
}, [setContentElement]);
|
|
182
|
-
|
|
183
|
-
useEffect(() => {
|
|
184
|
-
const handleKeyDown = (event: KeyboardEvent) => {
|
|
185
|
-
if (event.key === 'Escape') {
|
|
186
|
-
setIsOpen(false);
|
|
187
|
-
}
|
|
188
|
-
if (event.key === 'Tab') {
|
|
189
|
-
if (!firstFocusableElement || !lastFocusableElement) return;
|
|
190
|
-
|
|
191
|
-
if (event.shiftKey) {
|
|
192
|
-
if (document.activeElement === firstFocusableElement) {
|
|
193
|
-
event.preventDefault();
|
|
194
|
-
lastFocusableElement.focus();
|
|
195
|
-
}
|
|
196
|
-
} else {
|
|
197
|
-
if (document.activeElement === lastFocusableElement) {
|
|
198
|
-
event.preventDefault();
|
|
199
|
-
firstFocusableElement.focus();
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
};
|
|
204
|
-
|
|
205
|
-
document.addEventListener('keydown', handleKeyDown);
|
|
206
|
-
|
|
207
|
-
return () => {
|
|
208
|
-
document.removeEventListener('keydown', handleKeyDown);
|
|
209
|
-
};
|
|
210
|
-
}, [setIsOpen, firstFocusableElement, lastFocusableElement]);
|
|
211
|
-
|
|
212
|
-
useEffect(() => {
|
|
213
|
-
if (isOpen) {
|
|
214
|
-
// Note: overflow-hidden is now handled by RemoveScroll in MorphingDialogContainer
|
|
215
|
-
const focusableElements = containerRef.current?.querySelectorAll(
|
|
216
|
-
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
|
|
217
|
-
);
|
|
218
|
-
if (focusableElements && focusableElements.length > 0) {
|
|
219
|
-
setFirstFocusableElement(focusableElements[0] as HTMLElement);
|
|
220
|
-
setLastFocusableElement(
|
|
221
|
-
focusableElements[focusableElements.length - 1] as HTMLElement
|
|
222
|
-
);
|
|
223
|
-
(focusableElements[0] as HTMLElement).focus();
|
|
224
|
-
}
|
|
225
|
-
} else {
|
|
226
|
-
triggerRef.current?.focus();
|
|
227
|
-
}
|
|
228
|
-
}, [isOpen, triggerRef]);
|
|
229
|
-
|
|
230
|
-
useClickOutside(containerRef, () => {
|
|
231
|
-
if (isOpen) {
|
|
232
|
-
setIsOpen(false);
|
|
233
|
-
}
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
return (
|
|
237
|
-
<motion.div
|
|
238
|
-
ref={containerRef}
|
|
239
|
-
layoutId={`dialog-${uniqueId}`}
|
|
240
|
-
className={className}
|
|
241
|
-
style={style}
|
|
242
|
-
role='dialog'
|
|
243
|
-
aria-modal='true'
|
|
244
|
-
aria-labelledby={`motion-ui-morphing-dialog-title-${uniqueId}`}
|
|
245
|
-
aria-describedby={`motion-ui-morphing-dialog-description-${uniqueId}`}
|
|
246
|
-
>
|
|
247
|
-
{children}
|
|
248
|
-
</motion.div>
|
|
249
|
-
);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
export type MorphingDialogContainerProps = {
|
|
253
|
-
children: React.ReactNode;
|
|
254
|
-
className?: string;
|
|
255
|
-
style?: React.CSSProperties;
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
function MorphingDialogContainer({ children }: MorphingDialogContainerProps) {
|
|
259
|
-
const { isOpen, uniqueId, contentElement } = useMorphingDialog();
|
|
260
|
-
const [mounted, setMounted] = useState(false);
|
|
261
|
-
|
|
262
|
-
useEffect(() => {
|
|
263
|
-
setMounted(true);
|
|
264
|
-
return () => setMounted(false);
|
|
265
|
-
}, []);
|
|
266
|
-
|
|
267
|
-
if (!mounted) return null;
|
|
268
|
-
|
|
269
|
-
// Build shards array - only include contentElement if it's available
|
|
270
|
-
const shards = contentElement ? [contentElement] : [];
|
|
271
|
-
|
|
272
|
-
return createPortal(
|
|
273
|
-
<AnimatePresence initial={false} mode='sync'>
|
|
274
|
-
{isOpen && (
|
|
275
|
-
<RemoveScroll shards={shards} noIsolation>
|
|
276
|
-
<>
|
|
277
|
-
<motion.div
|
|
278
|
-
key={`backdrop-${uniqueId}`}
|
|
279
|
-
className='fixed inset-0 z-[60] h-full w-full bg-black/20 backdrop-blur-xs'
|
|
280
|
-
initial={{ opacity: 0 }}
|
|
281
|
-
animate={{ opacity: 1 }}
|
|
282
|
-
exit={{ opacity: 0 }}
|
|
283
|
-
/>
|
|
284
|
-
<div className='fixed inset-0 z-[60] flex items-center justify-center'>
|
|
285
|
-
{children}
|
|
286
|
-
</div>
|
|
287
|
-
</>
|
|
288
|
-
</RemoveScroll>
|
|
289
|
-
)}
|
|
290
|
-
</AnimatePresence>,
|
|
291
|
-
document.body
|
|
292
|
-
);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
export type MorphingDialogTitleProps = {
|
|
296
|
-
children: React.ReactNode;
|
|
297
|
-
className?: string;
|
|
298
|
-
style?: React.CSSProperties;
|
|
299
|
-
};
|
|
300
|
-
|
|
301
|
-
function MorphingDialogTitle({
|
|
302
|
-
children,
|
|
303
|
-
className,
|
|
304
|
-
style,
|
|
305
|
-
}: MorphingDialogTitleProps) {
|
|
306
|
-
const { uniqueId } = useMorphingDialog();
|
|
307
|
-
|
|
308
|
-
return (
|
|
309
|
-
<motion.div
|
|
310
|
-
layoutId={`dialog-title-container-${uniqueId}`}
|
|
311
|
-
className={className}
|
|
312
|
-
style={style}
|
|
313
|
-
layout
|
|
314
|
-
>
|
|
315
|
-
{children}
|
|
316
|
-
</motion.div>
|
|
317
|
-
);
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
export type MorphingDialogSubtitleProps = {
|
|
321
|
-
children: React.ReactNode;
|
|
322
|
-
className?: string;
|
|
323
|
-
style?: React.CSSProperties;
|
|
324
|
-
};
|
|
325
|
-
|
|
326
|
-
function MorphingDialogSubtitle({
|
|
327
|
-
children,
|
|
328
|
-
className,
|
|
329
|
-
style,
|
|
330
|
-
}: MorphingDialogSubtitleProps) {
|
|
331
|
-
const { uniqueId } = useMorphingDialog();
|
|
332
|
-
|
|
333
|
-
return (
|
|
334
|
-
<motion.div
|
|
335
|
-
layoutId={`dialog-subtitle-container-${uniqueId}`}
|
|
336
|
-
className={className}
|
|
337
|
-
style={style}
|
|
338
|
-
>
|
|
339
|
-
{children}
|
|
340
|
-
</motion.div>
|
|
341
|
-
);
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
export type MorphingDialogDescriptionProps = {
|
|
345
|
-
children: React.ReactNode;
|
|
346
|
-
className?: string;
|
|
347
|
-
disableLayoutAnimation?: boolean;
|
|
348
|
-
variants?: {
|
|
349
|
-
initial: Variant;
|
|
350
|
-
animate: Variant;
|
|
351
|
-
exit: Variant;
|
|
352
|
-
};
|
|
353
|
-
};
|
|
354
|
-
|
|
355
|
-
function MorphingDialogDescription({
|
|
356
|
-
children,
|
|
357
|
-
className,
|
|
358
|
-
variants,
|
|
359
|
-
disableLayoutAnimation,
|
|
360
|
-
}: MorphingDialogDescriptionProps) {
|
|
361
|
-
const { uniqueId } = useMorphingDialog();
|
|
362
|
-
|
|
363
|
-
return (
|
|
364
|
-
<motion.div
|
|
365
|
-
key={`dialog-description-${uniqueId}`}
|
|
366
|
-
layoutId={
|
|
367
|
-
disableLayoutAnimation
|
|
368
|
-
? undefined
|
|
369
|
-
: `dialog-description-content-${uniqueId}`
|
|
370
|
-
}
|
|
371
|
-
variants={variants}
|
|
372
|
-
className={className}
|
|
373
|
-
initial='initial'
|
|
374
|
-
animate='animate'
|
|
375
|
-
exit='exit'
|
|
376
|
-
id={`dialog-description-${uniqueId}`}
|
|
377
|
-
>
|
|
378
|
-
{children}
|
|
379
|
-
</motion.div>
|
|
380
|
-
);
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
export type MorphingDialogImageProps = {
|
|
384
|
-
src: string;
|
|
385
|
-
alt: string;
|
|
386
|
-
className?: string;
|
|
387
|
-
style?: React.CSSProperties;
|
|
388
|
-
};
|
|
389
|
-
|
|
390
|
-
function MorphingDialogImage({
|
|
391
|
-
src,
|
|
392
|
-
alt,
|
|
393
|
-
className,
|
|
394
|
-
style,
|
|
395
|
-
}: MorphingDialogImageProps) {
|
|
396
|
-
const { uniqueId } = useMorphingDialog();
|
|
397
|
-
|
|
398
|
-
return (
|
|
399
|
-
<motion.img
|
|
400
|
-
src={src}
|
|
401
|
-
alt={alt}
|
|
402
|
-
className={cn(className)}
|
|
403
|
-
layoutId={`dialog-img-${uniqueId}`}
|
|
404
|
-
style={style}
|
|
405
|
-
/>
|
|
406
|
-
);
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
export type MorphingDialogCloseProps = {
|
|
410
|
-
children?: React.ReactNode;
|
|
411
|
-
className?: string;
|
|
412
|
-
variants?: {
|
|
413
|
-
initial: Variant;
|
|
414
|
-
animate: Variant;
|
|
415
|
-
exit: Variant;
|
|
416
|
-
};
|
|
417
|
-
};
|
|
418
|
-
|
|
419
|
-
function MorphingDialogClose({
|
|
420
|
-
children,
|
|
421
|
-
className,
|
|
422
|
-
variants,
|
|
423
|
-
}: MorphingDialogCloseProps) {
|
|
424
|
-
const { setIsOpen, uniqueId } = useMorphingDialog();
|
|
425
|
-
|
|
426
|
-
const handleClose = useCallback(() => {
|
|
427
|
-
setIsOpen(false);
|
|
428
|
-
}, [setIsOpen]);
|
|
429
|
-
|
|
430
|
-
return (
|
|
431
|
-
<motion.button
|
|
432
|
-
onClick={handleClose}
|
|
433
|
-
type='button'
|
|
434
|
-
aria-label='Close dialog'
|
|
435
|
-
key={`dialog-close-${uniqueId}`}
|
|
436
|
-
className={cn('absolute top-6 right-6', className)}
|
|
437
|
-
initial='initial'
|
|
438
|
-
animate='animate'
|
|
439
|
-
exit='exit'
|
|
440
|
-
variants={variants}
|
|
441
|
-
>
|
|
442
|
-
{children || <XIcon size={24} />}
|
|
443
|
-
</motion.button>
|
|
444
|
-
);
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
export {
|
|
448
|
-
MorphingDialog,
|
|
449
|
-
MorphingDialogTrigger,
|
|
450
|
-
MorphingDialogContainer,
|
|
451
|
-
MorphingDialogContent,
|
|
452
|
-
MorphingDialogClose,
|
|
453
|
-
MorphingDialogTitle,
|
|
454
|
-
MorphingDialogSubtitle,
|
|
455
|
-
MorphingDialogDescription,
|
|
456
|
-
MorphingDialogImage,
|
|
457
|
-
};
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import * as React from "react"
|
|
4
|
-
import * as PopoverPrimitive from "@radix-ui/react-popover"
|
|
5
|
-
|
|
6
|
-
import { cn } from "@/lib/utils"
|
|
7
|
-
|
|
8
|
-
const Popover = PopoverPrimitive.Root
|
|
9
|
-
|
|
10
|
-
const PopoverTrigger = PopoverPrimitive.Trigger
|
|
11
|
-
|
|
12
|
-
const PopoverAnchor = PopoverPrimitive.Anchor
|
|
13
|
-
|
|
14
|
-
const PopoverContent = React.forwardRef<
|
|
15
|
-
React.ElementRef<typeof PopoverPrimitive.Content>,
|
|
16
|
-
React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
|
|
17
|
-
>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
|
|
18
|
-
<PopoverPrimitive.Portal>
|
|
19
|
-
<PopoverPrimitive.Content
|
|
20
|
-
ref={ref}
|
|
21
|
-
align={align}
|
|
22
|
-
sideOffset={sideOffset}
|
|
23
|
-
className={cn(
|
|
24
|
-
"z-50 w-72 rounded-md border bg-zinc-900 border-zinc-800 p-4 text-zinc-100 shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-[--radix-popover-content-transform-origin]",
|
|
25
|
-
className
|
|
26
|
-
)}
|
|
27
|
-
{...props}
|
|
28
|
-
/>
|
|
29
|
-
</PopoverPrimitive.Portal>
|
|
30
|
-
))
|
|
31
|
-
PopoverContent.displayName = PopoverPrimitive.Content.displayName
|
|
32
|
-
|
|
33
|
-
export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor }
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import * as React from "react"
|
|
4
|
-
import * as ProgressPrimitive from "@radix-ui/react-progress"
|
|
5
|
-
|
|
6
|
-
import { cn } from "@/lib/utils"
|
|
7
|
-
|
|
8
|
-
const Progress = React.forwardRef<
|
|
9
|
-
React.ElementRef<typeof ProgressPrimitive.Root>,
|
|
10
|
-
React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>
|
|
11
|
-
>(({ className, value, ...props }, ref) => (
|
|
12
|
-
<ProgressPrimitive.Root
|
|
13
|
-
ref={ref}
|
|
14
|
-
className={cn(
|
|
15
|
-
"relative h-2 w-full overflow-hidden rounded-full bg-primary/20",
|
|
16
|
-
className
|
|
17
|
-
)}
|
|
18
|
-
{...props}
|
|
19
|
-
>
|
|
20
|
-
<ProgressPrimitive.Indicator
|
|
21
|
-
className="h-full w-full flex-1 bg-primary transition-all"
|
|
22
|
-
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
|
|
23
|
-
/>
|
|
24
|
-
</ProgressPrimitive.Root>
|
|
25
|
-
))
|
|
26
|
-
Progress.displayName = ProgressPrimitive.Root.displayName
|
|
27
|
-
|
|
28
|
-
export { Progress }
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
|
|
3
|
-
import * as React from "react"
|
|
4
|
-
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
|
|
5
|
-
|
|
6
|
-
import { cn } from "@/lib/utils"
|
|
7
|
-
|
|
8
|
-
const ScrollArea = React.forwardRef<
|
|
9
|
-
React.ElementRef<typeof ScrollAreaPrimitive.Root>,
|
|
10
|
-
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>
|
|
11
|
-
>(({ className, children, ...props }, ref) => (
|
|
12
|
-
<ScrollAreaPrimitive.Root
|
|
13
|
-
ref={ref}
|
|
14
|
-
className={cn("relative overflow-hidden", className)}
|
|
15
|
-
{...props}
|
|
16
|
-
>
|
|
17
|
-
<ScrollAreaPrimitive.Viewport className="h-full w-full rounded-[inherit]">
|
|
18
|
-
{children}
|
|
19
|
-
</ScrollAreaPrimitive.Viewport>
|
|
20
|
-
<ScrollBar />
|
|
21
|
-
<ScrollAreaPrimitive.Corner />
|
|
22
|
-
</ScrollAreaPrimitive.Root>
|
|
23
|
-
))
|
|
24
|
-
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName
|
|
25
|
-
|
|
26
|
-
const ScrollBar = React.forwardRef<
|
|
27
|
-
React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,
|
|
28
|
-
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>
|
|
29
|
-
>(({ className, orientation = "vertical", ...props }, ref) => (
|
|
30
|
-
<ScrollAreaPrimitive.ScrollAreaScrollbar
|
|
31
|
-
ref={ref}
|
|
32
|
-
orientation={orientation}
|
|
33
|
-
className={cn(
|
|
34
|
-
"flex touch-none select-none transition-colors",
|
|
35
|
-
orientation === "vertical" &&
|
|
36
|
-
"h-full w-2.5 border-l border-l-transparent p-[1px]",
|
|
37
|
-
orientation === "horizontal" &&
|
|
38
|
-
"h-2.5 flex-col border-t border-t-transparent p-[1px]",
|
|
39
|
-
className
|
|
40
|
-
)}
|
|
41
|
-
{...props}
|
|
42
|
-
>
|
|
43
|
-
<ScrollAreaPrimitive.ScrollAreaThumb className="relative flex-1 rounded-full bg-border" />
|
|
44
|
-
</ScrollAreaPrimitive.ScrollAreaScrollbar>
|
|
45
|
-
))
|
|
46
|
-
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName
|
|
47
|
-
|
|
48
|
-
export { ScrollArea, ScrollBar }
|