diffhub 0.1.1 → 0.1.2

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.
Files changed (154) hide show
  1. package/.next/standalone/apps/web/.next/BUILD_ID +1 -1
  2. package/.next/standalone/apps/web/.next/build-manifest.json +3 -3
  3. package/.next/standalone/apps/web/.next/prerender-manifest.json +3 -3
  4. package/.next/standalone/apps/web/.next/server/app/_global-error.html +1 -1
  5. package/.next/standalone/apps/web/.next/server/app/_global-error.rsc +1 -1
  6. package/.next/standalone/apps/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  7. package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  8. package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  9. package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  10. package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  11. package/.next/standalone/apps/web/.next/server/app/_not-found/page.js +1 -1
  12. package/.next/standalone/apps/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  13. package/.next/standalone/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  14. package/.next/standalone/apps/web/.next/server/app/_not-found.html +1 -1
  15. package/.next/standalone/apps/web/.next/server/app/_not-found.rsc +16 -15
  16. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_full.segment.rsc +16 -15
  17. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  18. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_index.segment.rsc +5 -4
  19. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  20. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  21. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  22. package/.next/standalone/apps/web/.next/server/app/api/comments/route.js +1 -1
  23. package/.next/standalone/apps/web/.next/server/app/api/comments/route.js.nft.json +1 -1
  24. package/.next/standalone/apps/web/.next/server/app/api/diff/route.js +2 -2
  25. package/.next/standalone/apps/web/.next/server/app/api/diff/route.js.nft.json +1 -1
  26. package/.next/standalone/apps/web/.next/server/app/api/discard/route.js +2 -2
  27. package/.next/standalone/apps/web/.next/server/app/api/discard/route.js.nft.json +1 -1
  28. package/.next/standalone/apps/web/.next/server/app/api/file/route.js +2 -2
  29. package/.next/standalone/apps/web/.next/server/app/api/file/route.js.nft.json +1 -1
  30. package/.next/standalone/apps/web/.next/server/app/api/files/route.js +2 -2
  31. package/.next/standalone/apps/web/.next/server/app/api/files/route.js.nft.json +1 -1
  32. package/.next/standalone/apps/web/.next/server/app/index.html +1 -1
  33. package/.next/standalone/apps/web/.next/server/app/index.rsc +15 -14
  34. package/.next/standalone/apps/web/.next/server/app/index.segments/__PAGE__.segment.rsc +3 -3
  35. package/.next/standalone/apps/web/.next/server/app/index.segments/_full.segment.rsc +15 -14
  36. package/.next/standalone/apps/web/.next/server/app/index.segments/_head.segment.rsc +4 -4
  37. package/.next/standalone/apps/web/.next/server/app/index.segments/_index.segment.rsc +5 -4
  38. package/.next/standalone/apps/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  39. package/.next/standalone/apps/web/.next/server/app/page/react-loadable-manifest.json +2 -2
  40. package/.next/standalone/apps/web/.next/server/app/page.js +2 -2
  41. package/.next/standalone/apps/web/.next/server/app/page.js.nft.json +1 -1
  42. package/.next/standalone/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
  43. package/.next/standalone/apps/web/.next/server/chunks/[root-of-the-server]__05ejtyr._.js +3 -0
  44. package/.next/standalone/apps/web/.next/server/chunks/[root-of-the-server]__0e2dp4h._.js +3 -0
  45. package/.next/standalone/apps/web/.next/server/chunks/[root-of-the-server]__0egk6ui._.js +3 -0
  46. package/.next/standalone/apps/web/.next/server/chunks/[root-of-the-server]__0i6i-~n._.js +3 -0
  47. package/.next/standalone/apps/web/.next/server/chunks/[root-of-the-server]__0sv4hr9._.js +3 -0
  48. package/.next/standalone/apps/web/.next/server/chunks/[root-of-the-server]__0t.tl18._.js +3 -0
  49. package/.next/standalone/apps/web/.next/server/chunks/ssr/{[root-of-the-server]__06b81~v._.js → [root-of-the-server]__0giwc4b._.js} +2 -2
  50. package/.next/standalone/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0jit913._.js +3 -0
  51. package/.next/standalone/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0v19a7g._.js +3 -0
  52. package/.next/standalone/apps/web/.next/server/chunks/ssr/_0f40lcw._.js +3 -0
  53. package/.next/standalone/apps/web/.next/server/chunks/ssr/_0oc3qg_._.js +3 -3
  54. package/.next/standalone/apps/web/.next/server/chunks/ssr/{apps_web_0b_ykcu._.js → _0qo42r0._.js} +2 -2
  55. package/.next/standalone/apps/web/.next/server/chunks/ssr/{apps_web_08kf15u._.js → apps_web_0758ax4._.js} +2 -2
  56. package/.next/standalone/apps/web/.next/server/chunks/ssr/node_modules_0v8w2j~._.js +70 -0
  57. package/.next/standalone/apps/web/.next/server/middleware-build-manifest.js +3 -3
  58. package/.next/standalone/apps/web/.next/server/pages/404.html +1 -1
  59. package/.next/standalone/apps/web/.next/server/pages/500.html +1 -1
  60. package/.next/standalone/apps/web/.next/server/server-reference-manifest.js +1 -1
  61. package/.next/standalone/apps/web/.next/server/server-reference-manifest.json +1 -1
  62. package/.next/standalone/apps/web/.next/static/chunks/{0-ci0c9di0qo8.js → 00zp83w4g1v1r.js} +3 -3
  63. package/.next/standalone/apps/web/.next/static/chunks/042ip11u2i2z6.js +138 -0
  64. package/.next/standalone/apps/web/.next/static/chunks/085s9eg867ha-.js +1 -0
  65. package/.next/standalone/apps/web/.next/static/chunks/0_vmme_k_ff_u.js +67 -0
  66. package/.next/standalone/apps/web/.next/static/chunks/0ap~_hc7r17_6.js +1 -0
  67. package/.next/standalone/apps/web/.next/static/chunks/0nt5-rwas5thn.js +67 -0
  68. package/.next/standalone/apps/web/.next/static/chunks/0p~3-4_.v0cft.js +1 -0
  69. package/.next/standalone/apps/web/.next/static/chunks/0wx-2dr44ql-g.js +1 -0
  70. package/.next/standalone/apps/web/.next/static/chunks/{0syypqto3~pe_.js → 0y0o261rjun_2.js} +8 -8
  71. package/.next/standalone/apps/web/.next/static/chunks/0y5z3t-z1c8ks.js.map +5 -0
  72. package/.next/standalone/apps/web/.next/static/chunks/17b.xoi.b6rcl.js +1 -0
  73. package/.next/standalone/apps/web/.next/static/chunks/turbopack-0_n_4n~_4no2a.js +1 -0
  74. package/.next/standalone/apps/web/.next/static/chunks/turbopack-worker-0sjn--fhq~1cg.js +1 -0
  75. package/.next/standalone/apps/web/.next/static/media/diffs.worker.09unk0quktc_5.ts +1 -0
  76. package/.next/standalone/apps/web/package.json +4 -4
  77. package/README.md +10 -3
  78. package/package.json +4 -4
  79. package/.next/standalone/apps/web/.next/server/chunks/[root-of-the-server]__05vwx85._.js +0 -3
  80. package/.next/standalone/apps/web/.next/server/chunks/[root-of-the-server]__09vmjc2._.js +0 -3
  81. package/.next/standalone/apps/web/.next/server/chunks/[root-of-the-server]__0etmu4u._.js +0 -3
  82. package/.next/standalone/apps/web/.next/server/chunks/[root-of-the-server]__0g-_a7n._.js +0 -3
  83. package/.next/standalone/apps/web/.next/server/chunks/[root-of-the-server]__0mshgfw._.js +0 -3
  84. package/.next/standalone/apps/web/.next/server/chunks/[root-of-the-server]__0qixima._.js +0 -3
  85. package/.next/standalone/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0f~hmsk._.js +0 -3
  86. package/.next/standalone/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0khyzju._.js +0 -3
  87. package/.next/standalone/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0l2mjim._.js +0 -70
  88. package/.next/standalone/apps/web/.next/server/chunks/ssr/_0kwaklj._.js +0 -3
  89. package/.next/standalone/apps/web/.next/static/chunks/0.ae0sud8tm7k.js +0 -204
  90. package/.next/standalone/apps/web/.next/static/chunks/0di~ntk7iivm4.js +0 -1
  91. package/.next/standalone/apps/web/.next/static/chunks/0pklg0nmdvay8.js +0 -1
  92. package/.next/standalone/apps/web/.next/static/chunks/0up9_7hiwl_dt.js +0 -1
  93. package/.next/standalone/apps/web/.next/static/chunks/0~984a88e4rp9.js +0 -204
  94. package/.next/standalone/apps/web/.next/static/chunks/13y8355z8m13w.js +0 -1
  95. package/.next/standalone/apps/web/AGENTS.md +0 -60
  96. package/.next/standalone/apps/web/CHANGELOG.md +0 -7
  97. package/.next/standalone/apps/web/CLAUDE.md +0 -1
  98. package/.next/standalone/apps/web/README.md +0 -78
  99. package/.next/standalone/apps/web/app/api/comments/route.ts +0 -20
  100. package/.next/standalone/apps/web/app/api/diff/route.ts +0 -15
  101. package/.next/standalone/apps/web/app/api/discard/route.ts +0 -15
  102. package/.next/standalone/apps/web/app/api/file/route.ts +0 -17
  103. package/.next/standalone/apps/web/app/api/files/route.ts +0 -14
  104. package/.next/standalone/apps/web/app/api/open/route.ts +0 -64
  105. package/.next/standalone/apps/web/app/favicon.ico +0 -0
  106. package/.next/standalone/apps/web/app/globals.css +0 -214
  107. package/.next/standalone/apps/web/app/layout.tsx +0 -52
  108. package/.next/standalone/apps/web/app/page.tsx +0 -6
  109. package/.next/standalone/apps/web/bin/diffhub.mjs +0 -147
  110. package/.next/standalone/apps/web/components/ContextMenu.tsx +0 -161
  111. package/.next/standalone/apps/web/components/DiffApp.tsx +0 -419
  112. package/.next/standalone/apps/web/components/DiffViewer.tsx +0 -565
  113. package/.next/standalone/apps/web/components/FileDiffHeader.tsx +0 -119
  114. package/.next/standalone/apps/web/components/FileList.tsx +0 -455
  115. package/.next/standalone/apps/web/components/KeyboardShortcutsDialog.tsx +0 -79
  116. package/.next/standalone/apps/web/components/SidebarHelpMenu.tsx +0 -86
  117. package/.next/standalone/apps/web/components/StatusBar.tsx +0 -212
  118. package/.next/standalone/apps/web/components/icons/file-status-icons.tsx +0 -48
  119. package/.next/standalone/apps/web/components/theme-provider.tsx +0 -12
  120. package/.next/standalone/apps/web/components/ui/button.tsx +0 -90
  121. package/.next/standalone/apps/web/components/ui/empty.tsx +0 -82
  122. package/.next/standalone/apps/web/components/ui/input.tsx +0 -18
  123. package/.next/standalone/apps/web/components/ui/kbd.tsx +0 -14
  124. package/.next/standalone/apps/web/components/ui/separator.tsx +0 -23
  125. package/.next/standalone/apps/web/components/ui/sheet.tsx +0 -109
  126. package/.next/standalone/apps/web/components/ui/sidebar.tsx +0 -700
  127. package/.next/standalone/apps/web/components/ui/skeleton.tsx +0 -9
  128. package/.next/standalone/apps/web/components/ui/toggle.tsx +0 -35
  129. package/.next/standalone/apps/web/components/ui/tooltip.tsx +0 -52
  130. package/.next/standalone/apps/web/components.json +0 -27
  131. package/.next/standalone/apps/web/lib/comments.ts +0 -52
  132. package/.next/standalone/apps/web/lib/export-comments.ts +0 -13
  133. package/.next/standalone/apps/web/lib/git.ts +0 -201
  134. package/.next/standalone/apps/web/lib/use-mobile.ts +0 -19
  135. package/.next/standalone/apps/web/lib/utils.ts +0 -5
  136. package/.next/standalone/apps/web/next.config.ts +0 -19
  137. package/.next/standalone/apps/web/oxfmt.config.ts +0 -6
  138. package/.next/standalone/apps/web/oxlint.config.ts +0 -13
  139. package/.next/standalone/apps/web/postcss.config.mjs +0 -7
  140. package/.next/standalone/apps/web/public/file.svg +0 -1
  141. package/.next/standalone/apps/web/public/glide-variable-italic.woff2 +0 -0
  142. package/.next/standalone/apps/web/public/glide-variable.woff2 +0 -0
  143. package/.next/standalone/apps/web/public/globe.svg +0 -1
  144. package/.next/standalone/apps/web/public/next.svg +0 -1
  145. package/.next/standalone/apps/web/public/operator-mono-book-italic.woff2 +0 -0
  146. package/.next/standalone/apps/web/public/operator-mono-book.woff2 +0 -0
  147. package/.next/standalone/apps/web/public/operator-mono-medium-italic.woff2 +0 -0
  148. package/.next/standalone/apps/web/public/operator-mono-medium.woff2 +0 -0
  149. package/.next/standalone/apps/web/public/vercel.svg +0 -1
  150. package/.next/standalone/apps/web/public/window.svg +0 -1
  151. package/.next/standalone/apps/web/tsconfig.json +0 -34
  152. /package/.next/standalone/apps/web/.next/static/{ZhI_-YaFho-fQoajjgwSH → mAVCL4HCmtJwT35feBPdK}/_buildManifest.js +0 -0
  153. /package/.next/standalone/apps/web/.next/static/{ZhI_-YaFho-fQoajjgwSH → mAVCL4HCmtJwT35feBPdK}/_clientMiddlewareManifest.js +0 -0
  154. /package/.next/standalone/apps/web/.next/static/{ZhI_-YaFho-fQoajjgwSH → mAVCL4HCmtJwT35feBPdK}/_ssgManifest.js +0 -0
@@ -1,212 +0,0 @@
1
- "use client";
2
-
3
- import {
4
- CopySimpleIcon,
5
- CheckIcon,
6
- ChevronDownIcon,
7
- SunIcon,
8
- MoonIcon,
9
- SplitIcon,
10
- ArrowRightIcon,
11
- } from "blode-icons-react";
12
- import { useTheme } from "next-themes";
13
- import { useEffect, useRef, useState } from "react";
14
- import type { Comment } from "@/lib/comments";
15
- import { exportCommentsAsPrompt } from "@/lib/export-comments";
16
- import { Button } from "@/components/ui/button";
17
- import { cn } from "@/lib/utils";
18
-
19
- export type DiffMode = "all" | "uncommitted";
20
-
21
- const DIFF_MODES: { value: DiffMode; label: string }[] = [
22
- { label: "All changes", value: "all" },
23
- { label: "Uncommitted changes", value: "uncommitted" },
24
- ];
25
-
26
- interface StatusBarProps {
27
- branch: string;
28
- baseBranch: string;
29
- insertions: number;
30
- deletions: number;
31
- fileCount: number;
32
- refreshing: boolean;
33
- lastUpdated: Date | null;
34
- comments: Comment[];
35
- diffMode: DiffMode;
36
- onDiffModeChange: (mode: DiffMode) => void;
37
- layout: "split" | "stacked";
38
- onLayoutChange: (l: "split" | "stacked") => void;
39
- }
40
-
41
- export const StatusBar = ({
42
- branch,
43
- baseBranch,
44
- insertions,
45
- deletions,
46
- fileCount,
47
- refreshing,
48
- lastUpdated,
49
- comments,
50
- diffMode,
51
- onDiffModeChange,
52
- layout,
53
- onLayoutChange,
54
- }: StatusBarProps) => {
55
- const [copied, setCopied] = useState(false);
56
- const [modeMenuOpen, setModeMenuOpen] = useState(false);
57
- const modeMenuRef = useRef<HTMLDivElement>(null);
58
- const { resolvedTheme, setTheme } = useTheme();
59
-
60
- const copiedTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
61
-
62
- // oxlint-disable-next-line react-perf/jsx-no-new-function-as-prop
63
- const copyCommentsAsPrompt = async () => {
64
- try {
65
- const text = exportCommentsAsPrompt(comments);
66
- await navigator.clipboard.writeText(text);
67
- if (copiedTimerRef.current) {
68
- clearTimeout(copiedTimerRef.current);
69
- }
70
- setCopied(true);
71
- copiedTimerRef.current = setTimeout(() => setCopied(false), 2000);
72
- } catch {
73
- // clipboard unavailable — don't flip copied state
74
- }
75
- };
76
-
77
- useEffect(() => {
78
- if (!modeMenuOpen) {
79
- return;
80
- }
81
- const handleClick = (e: MouseEvent) => {
82
- if (modeMenuRef.current && !modeMenuRef.current.contains(e.target as Node)) {
83
- setModeMenuOpen(false);
84
- }
85
- };
86
- document.addEventListener("mousedown", handleClick);
87
- return () => document.removeEventListener("mousedown", handleClick);
88
- }, [modeMenuOpen]);
89
-
90
- return (
91
- <header className="flex items-center gap-2 border-b border-border bg-card px-4 py-2.5 text-sm">
92
- {/* Branch comparison badges */}
93
- <div className="flex items-center gap-1.5">
94
- <span className="rounded-md border border-border bg-background px-2.5 py-1 font-mono text-xs font-medium text-foreground">
95
- {branch}
96
- </span>
97
- <ArrowRightIcon size={12} className="text-muted-foreground/50 shrink-0" />
98
- <span className="rounded-md border border-border bg-background px-2.5 py-1 font-mono text-xs text-muted-foreground">
99
- {baseBranch}
100
- </span>
101
- </div>
102
-
103
- {/* Stats */}
104
- <div className="flex items-center gap-2">
105
- <span className="text-xs font-mono text-muted-foreground">
106
- {fileCount} {fileCount === 1 ? "file" : "files"}
107
- </span>
108
- {insertions > 0 && <span className="text-xs font-mono text-diff-green">+{insertions}</span>}
109
- {deletions > 0 && <span className="text-xs font-mono text-destructive">−{deletions}</span>}
110
- </div>
111
-
112
- <div className="flex-1" />
113
-
114
- <div className="flex items-center gap-0.5">
115
- {/* Live indicator */}
116
- {lastUpdated && (
117
- <span
118
- className={cn(
119
- "size-1.5 rounded-full bg-diff-green mx-1.5",
120
- refreshing && "animate-pulse",
121
- )}
122
- />
123
- )}
124
-
125
- {/* Diff mode dropdown */}
126
- <div className="relative" ref={modeMenuRef}>
127
- <Button
128
- variant="ghost"
129
- size="xs"
130
- // oxlint-disable-next-line react-perf/jsx-no-new-function-as-prop
131
- onClick={() => setModeMenuOpen((o) => !o)}
132
- className="text-muted-foreground hover:text-foreground hover:bg-secondary gap-1"
133
- >
134
- {diffMode === "uncommitted" ? "Uncommitted" : "All changes"}
135
- <ChevronDownIcon
136
- size={10}
137
- className={cn("transition-transform duration-150", modeMenuOpen && "rotate-180")}
138
- />
139
- </Button>
140
-
141
- {modeMenuOpen && (
142
- <div className="absolute right-0 top-full mt-1 z-50 min-w-[200px] rounded-lg border border-border bg-card shadow-lg dark:shadow-none py-1 overflow-hidden">
143
- {DIFF_MODES.map(({ value, label }) => (
144
- <button
145
- type="button"
146
- key={value}
147
- className="flex w-full items-center justify-between px-3 py-2 text-sm text-left hover:bg-secondary/50 transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring/50"
148
- // oxlint-disable-next-line react-perf/jsx-no-new-function-as-prop
149
- onClick={() => {
150
- onDiffModeChange(value);
151
- setModeMenuOpen(false);
152
- }}
153
- >
154
- <span className={cn("text-foreground", diffMode === value && "font-medium")}>
155
- {label}
156
- </span>
157
- {diffMode === value && (
158
- <CheckIcon size={14} className="text-diff-green shrink-0" />
159
- )}
160
- </button>
161
- ))}
162
- </div>
163
- )}
164
- </div>
165
-
166
- {/* Comments export */}
167
- {comments.length > 0 && (
168
- <Button
169
- variant="ghost"
170
- size="xs"
171
- onClick={copyCommentsAsPrompt}
172
- className="text-muted-foreground hover:text-foreground hover:bg-secondary"
173
- title="Copy all comments as AI prompt"
174
- >
175
- {copied ? (
176
- <CheckIcon data-icon="inline-start" />
177
- ) : (
178
- <CopySimpleIcon data-icon="inline-start" />
179
- )}
180
- {copied
181
- ? "Copied!"
182
- : `Copy ${comments.length} comment${comments.length === 1 ? "" : "s"}`}
183
- </Button>
184
- )}
185
-
186
- {/* Layout toggle */}
187
- <Button
188
- variant="ghost"
189
- size="icon-xs"
190
- // oxlint-disable-next-line react-perf/jsx-no-new-function-as-prop
191
- onClick={() => onLayoutChange(layout === "split" ? "stacked" : "split")}
192
- className="text-muted-foreground hover:text-foreground hover:bg-secondary"
193
- title={layout === "split" ? "Switch to unified view (S)" : "Switch to split view (S)"}
194
- >
195
- <SplitIcon size={14} />
196
- </Button>
197
-
198
- {/* Theme toggle */}
199
- <Button
200
- variant="ghost"
201
- size="icon-xs"
202
- // oxlint-disable-next-line react-perf/jsx-no-new-function-as-prop
203
- onClick={() => setTheme(resolvedTheme === "dark" ? "light" : "dark")}
204
- className="text-muted-foreground hover:text-foreground hover:bg-secondary"
205
- title={resolvedTheme === "dark" ? "Switch to light mode" : "Switch to dark mode"}
206
- >
207
- {resolvedTheme === "dark" ? <SunIcon size={14} /> : <MoonIcon size={14} />}
208
- </Button>
209
- </div>
210
- </header>
211
- );
212
- };
@@ -1,48 +0,0 @@
1
- import type { SVGProps } from "react";
2
-
3
- type IconProps = SVGProps<SVGSVGElement> & { size?: number };
4
-
5
- /** Modified file */
6
- export const FileDiffIcon = ({ size = 16, ...props }: IconProps) => (
7
- <svg
8
- viewBox="0 0 16 16"
9
- width={size}
10
- height={size}
11
- fill="currentColor"
12
- aria-hidden="true"
13
- focusable="false"
14
- {...props}
15
- >
16
- <path d="M1 1.75C1 .784 1.784 0 2.75 0h7.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16H2.75A1.75 1.75 0 0 1 1 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h10.5a.25.25 0 0 0 .25-.25V4.664a.25.25 0 0 0-.073-.177l-2.914-2.914a.25.25 0 0 0-.177-.073ZM8 3.25a.75.75 0 0 1 .75.75v1.5h1.5a.75.75 0 0 1 0 1.5h-1.5v1.5a.75.75 0 0 1-1.5 0V7h-1.5a.75.75 0 0 1 0-1.5h1.5V4A.75.75 0 0 1 8 3.25Zm-3 8a.75.75 0 0 1 .75-.75h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1-.75-.75Z" />
17
- </svg>
18
- );
19
-
20
- /** Added file */
21
- export const FileAddedIcon = ({ size = 16, ...props }: IconProps) => (
22
- <svg
23
- viewBox="0 0 16 16"
24
- width={size}
25
- height={size}
26
- fill="currentColor"
27
- aria-hidden="true"
28
- focusable="false"
29
- {...props}
30
- >
31
- <path d="M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V4.664a.25.25 0 0 0-.073-.177l-2.914-2.914a.25.25 0 0 0-.177-.073Zm4.48 3.758a.75.75 0 0 1 .755.745l.01 1.497h1.497a.75.75 0 0 1 0 1.5H9v1.507a.75.75 0 0 1-1.5 0V9.005l-1.502.01a.75.75 0 0 1-.01-1.5l1.507-.01-.01-1.492a.75.75 0 0 1 .745-.755Z" />
32
- </svg>
33
- );
34
-
35
- /** Removed file */
36
- export const FileRemovedIcon = ({ size = 16, ...props }: IconProps) => (
37
- <svg
38
- viewBox="0 0 16 16"
39
- width={size}
40
- height={size}
41
- fill="currentColor"
42
- aria-hidden="true"
43
- focusable="false"
44
- {...props}
45
- >
46
- <path d="M2 1.75C2 .784 2.784 0 3.75 0h6.586c.464 0 .909.184 1.237.513l2.914 2.914c.329.328.513.773.513 1.237v9.586A1.75 1.75 0 0 1 13.25 16h-9.5A1.75 1.75 0 0 1 2 14.25Zm1.75-.25a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25h9.5a.25.25 0 0 0 .25-.25V4.664a.25.25 0 0 0-.073-.177l-2.914-2.914a.25.25 0 0 0-.177-.073Zm4.5 6h2.242a.75.75 0 0 1 0 1.5h-2.24l-2.254.015a.75.75 0 0 1-.01-1.5Z" />
47
- </svg>
48
- );
@@ -1,12 +0,0 @@
1
- "use client";
2
-
3
- import * as React from "react";
4
- import { ThemeProvider as NextThemesProvider } from "next-themes";
5
- import type { ThemeProviderProps } from "next-themes";
6
-
7
- export const ThemeProvider = ({
8
- children,
9
- ...props
10
- }: ThemeProviderProps & { children?: React.ReactNode }) => (
11
- <NextThemesProvider {...props}>{children}</NextThemesProvider>
12
- );
@@ -1,90 +0,0 @@
1
- import { mergeProps } from "@base-ui/react/merge-props";
2
- import { useRender } from "@base-ui/react/use-render";
3
- import { cva } from "class-variance-authority";
4
- import type { VariantProps } from "class-variance-authority";
5
- import type * as React from "react";
6
-
7
- import { cn } from "@/lib/utils";
8
-
9
- const buttonVariants = cva(
10
- "group/button inline-flex shrink-0 select-none items-center justify-center whitespace-nowrap rounded-lg border border-transparent bg-clip-padding font-sans font-medium text-sm outline-none transition-[color,background-color,border-color,box-shadow,opacity,transform] duration-150 ease-out focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/50 focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-45 aria-disabled:pointer-events-none aria-disabled:cursor-not-allowed aria-disabled:opacity-45 aria-invalid:border-destructive aria-invalid:ring-2 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
11
- {
12
- defaultVariants: {
13
- size: "default",
14
- variant: "default",
15
- },
16
- variants: {
17
- size: {
18
- default:
19
- "h-10 gap-1.5 px-3 has-data-[icon=inline-end]:pr-2.5 has-data-[icon=inline-start]:pl-2.5",
20
- icon: "size-10",
21
- "icon-lg": "size-11",
22
- "icon-sm":
23
- "size-9 in-data-[slot=button-group]:rounded-lg rounded-[min(var(--radius-md),12px)]",
24
- "icon-xs":
25
- "size-8 in-data-[slot=button-group]:rounded-lg rounded-[min(var(--radius-md),10px)] [&_svg:not([class*='size-'])]:size-3",
26
- input:
27
- "h-[var(--field-height)] gap-2 rounded-[var(--field-radius)] px-[var(--field-padding-x)] py-[var(--field-padding-y)]",
28
- "input-sm":
29
- "h-[var(--field-height-sm)] gap-2 rounded-[var(--field-radius)] px-[var(--field-padding-x)] py-[var(--field-padding-y)]",
30
- lg: "h-11 gap-1.5 px-4 has-data-[icon=inline-end]:pr-3.5 has-data-[icon=inline-start]:pl-3.5",
31
- sm: "h-9 gap-1 in-data-[slot=button-group]:rounded-lg rounded-[min(var(--radius-md),12px)] px-3 text-[0.8rem] has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2 [&_svg:not([class*='size-'])]:size-3.5",
32
- xs: "h-8 gap-1 in-data-[slot=button-group]:rounded-lg rounded-[min(var(--radius-md),10px)] px-2.5 text-xs has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2 [&_svg:not([class*='size-'])]:size-3",
33
- },
34
- variant: {
35
- default:
36
- "bg-primary text-primary-foreground hover:bg-primary/90 active:bg-primary/95 aria-pressed:bg-primary/95",
37
- destructive:
38
- "bg-red-600 text-white hover:bg-red-700 focus-visible:border-red-600 focus-visible:ring-red-500/30 active:bg-red-800 aria-pressed:bg-red-800 dark:bg-red-500 dark:aria-pressed:bg-red-300 dark:active:bg-red-300 dark:hover:bg-red-400",
39
- destructiveSecondary:
40
- "border-red-200 text-red-700 hover:bg-red-50 active:bg-red-100 aria-pressed:bg-red-100 dark:border-red-800 dark:text-red-300 dark:aria-pressed:bg-red-950 dark:active:bg-red-950 dark:hover:bg-red-950/60",
41
- ghost:
42
- "hover:bg-muted hover:text-foreground active:bg-muted/80 aria-expanded:bg-muted aria-pressed:bg-muted/80 dark:aria-pressed:bg-muted/60 dark:active:bg-muted/60 dark:hover:bg-muted/50",
43
- input:
44
- "border-input bg-card font-normal font-sans text-base text-foreground leading-snug shadow-input hover:border-input-hover focus-visible:ring-2 focus-visible:ring-ring/15 focus-visible:ring-offset-1 focus-visible:ring-offset-background active:border-input-hover/80 aria-pressed:border-input-hover aria-invalid:border-destructive-foreground data-[placeholder]:text-placeholder-foreground",
45
- link: "text-primary underline-offset-4 hover:underline active:opacity-80 aria-pressed:underline aria-pressed:opacity-80",
46
- outline:
47
- "border-border bg-background hover:bg-muted hover:text-foreground active:bg-muted/80 aria-expanded:bg-muted aria-pressed:bg-muted/80 dark:border-input dark:bg-input/30 dark:aria-pressed:bg-input/60 dark:active:bg-input/60 dark:hover:bg-input/50",
48
- secondary:
49
- "bg-secondary text-secondary-foreground hover:bg-secondary/85 active:bg-secondary/75 aria-expanded:bg-secondary aria-pressed:bg-secondary/75",
50
- success:
51
- "bg-green-600 text-white hover:bg-green-700 focus-visible:border-green-600 focus-visible:ring-green-500/30 active:bg-green-800 aria-pressed:bg-green-800 dark:bg-green-500 dark:aria-pressed:bg-green-300 dark:active:bg-green-300 dark:hover:bg-green-400",
52
- successSecondary:
53
- "border-green-200 text-green-700 hover:bg-green-50 active:bg-green-100 aria-pressed:bg-green-100 dark:border-green-800 dark:text-green-300 dark:aria-pressed:bg-green-950 dark:active:bg-green-950 dark:hover:bg-green-950/60",
54
- warning:
55
- "bg-yellow-600 text-white hover:bg-yellow-700 focus-visible:border-yellow-600 focus-visible:ring-yellow-500/30 active:bg-yellow-800 aria-pressed:bg-yellow-800 dark:bg-yellow-500 dark:text-yellow-950 dark:aria-pressed:bg-yellow-300 dark:active:bg-yellow-300 dark:hover:bg-yellow-400",
56
- warningSecondary:
57
- "border-yellow-200 text-yellow-700 hover:bg-yellow-50 active:bg-yellow-100 aria-pressed:bg-yellow-100 dark:border-yellow-800 dark:text-yellow-300 dark:aria-pressed:bg-yellow-950 dark:active:bg-yellow-950 dark:hover:bg-yellow-950/60",
58
- },
59
- },
60
- },
61
- );
62
-
63
- const Button = ({
64
- className,
65
- variant = "default",
66
- size = "default",
67
- asChild = false,
68
- children,
69
- ...props
70
- }: React.ComponentProps<"button"> &
71
- VariantProps<typeof buttonVariants> & {
72
- asChild?: boolean;
73
- }) =>
74
- useRender({
75
- defaultTagName: "button",
76
- props: mergeProps<"button">(
77
- {
78
- className: cn(buttonVariants({ className, size, variant })),
79
- },
80
- asChild ? props : { ...props, children },
81
- ),
82
- render: asChild ? (children as React.ReactElement) : undefined,
83
- state: {
84
- size,
85
- slot: "button",
86
- variant,
87
- },
88
- });
89
-
90
- export { Button, buttonVariants };
@@ -1,82 +0,0 @@
1
- import { cva } from "class-variance-authority";
2
- import type { VariantProps } from "class-variance-authority";
3
- import type * as React from "react";
4
-
5
- import { cn } from "@/lib/utils";
6
-
7
- const Empty = ({ className, ...props }: React.ComponentProps<"div">) => (
8
- <div
9
- className={cn(
10
- "flex min-w-0 flex-1 flex-col items-center justify-center gap-6 text-balance rounded-lg border-dashed p-6 text-center md:p-12",
11
- className,
12
- )}
13
- data-slot="empty"
14
- {...props}
15
- />
16
- );
17
-
18
- const EmptyHeader = ({ className, ...props }: React.ComponentProps<"div">) => (
19
- <div
20
- className={cn("flex max-w-sm flex-col items-center gap-2 text-center", className)}
21
- data-slot="empty-header"
22
- {...props}
23
- />
24
- );
25
-
26
- const emptyMediaVariants = cva(
27
- "mb-2 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0",
28
- {
29
- defaultVariants: { variant: "default" },
30
- variants: {
31
- variant: {
32
- default: "bg-transparent",
33
- icon: "flex size-10 shrink-0 items-center justify-center rounded-lg bg-muted text-foreground [&_svg:not([class*='size-'])]:size-6",
34
- },
35
- },
36
- },
37
- );
38
-
39
- const EmptyMedia = ({
40
- className,
41
- variant = "default",
42
- ...props
43
- }: React.ComponentProps<"div"> & VariantProps<typeof emptyMediaVariants>) => (
44
- <div
45
- className={cn(emptyMediaVariants({ className, variant }))}
46
- data-slot="empty-icon"
47
- data-variant={variant}
48
- {...props}
49
- />
50
- );
51
-
52
- const EmptyTitle = ({ className, ...props }: React.ComponentProps<"div">) => (
53
- <div
54
- className={cn("font-medium text-lg tracking-tight", className)}
55
- data-slot="empty-title"
56
- {...props}
57
- />
58
- );
59
-
60
- const EmptyDescription = ({ className, ...props }: React.ComponentProps<"p">) => (
61
- <div
62
- className={cn(
63
- "text-muted-foreground text-sm/relaxed [&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4",
64
- className,
65
- )}
66
- data-slot="empty-description"
67
- {...props}
68
- />
69
- );
70
-
71
- const EmptyContent = ({ className, ...props }: React.ComponentProps<"div">) => (
72
- <div
73
- className={cn(
74
- "flex w-full min-w-0 max-w-sm flex-col items-center gap-4 text-balance text-sm",
75
- className,
76
- )}
77
- data-slot="empty-content"
78
- {...props}
79
- />
80
- );
81
-
82
- export { Empty, EmptyHeader, EmptyTitle, EmptyDescription, EmptyContent, EmptyMedia };
@@ -1,18 +0,0 @@
1
- import * as React from "react";
2
- import { Input as InputPrimitive } from "@base-ui/react/input";
3
-
4
- import { cn } from "@/lib/utils";
5
-
6
- const Input = ({ className, type, ...props }: React.ComponentProps<"input">) => (
7
- <InputPrimitive
8
- type={type}
9
- data-slot="input"
10
- className={cn(
11
- "h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
12
- className,
13
- )}
14
- {...props}
15
- />
16
- );
17
-
18
- export { Input };
@@ -1,14 +0,0 @@
1
- import type * as React from "react";
2
- import { cn } from "@/lib/utils";
3
-
4
- export const Kbd = ({ className, children, ...props }: React.ComponentProps<"kbd">) => (
5
- <kbd
6
- className={cn(
7
- "inline-flex h-5 items-center rounded border border-border bg-muted px-1.5 font-mono text-[10px] text-muted-foreground",
8
- className,
9
- )}
10
- {...props}
11
- >
12
- {children}
13
- </kbd>
14
- );
@@ -1,23 +0,0 @@
1
- "use client";
2
-
3
- import { Separator as SeparatorPrimitive } from "@base-ui/react/separator";
4
-
5
- import { cn } from "@/lib/utils";
6
-
7
- const Separator = ({
8
- className,
9
- orientation = "horizontal",
10
- ...props
11
- }: SeparatorPrimitive.Props) => (
12
- <SeparatorPrimitive
13
- data-slot="separator"
14
- orientation={orientation}
15
- className={cn(
16
- "shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch",
17
- className,
18
- )}
19
- {...props}
20
- />
21
- );
22
-
23
- export { Separator };
@@ -1,109 +0,0 @@
1
- "use client";
2
-
3
- import * as React from "react";
4
- import { Dialog as SheetPrimitive } from "@base-ui/react/dialog";
5
-
6
- import { cn } from "@/lib/utils";
7
- import { Button } from "@/components/ui/button";
8
- import { XIcon } from "lucide-react";
9
-
10
- const Sheet = ({ ...props }: SheetPrimitive.Root.Props) => (
11
- <SheetPrimitive.Root data-slot="sheet" {...props} />
12
- );
13
-
14
- const SheetTrigger = ({ ...props }: SheetPrimitive.Trigger.Props) => (
15
- <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />
16
- );
17
-
18
- const SheetClose = ({ ...props }: SheetPrimitive.Close.Props) => (
19
- <SheetPrimitive.Close data-slot="sheet-close" {...props} />
20
- );
21
-
22
- const SheetPortal = ({ ...props }: SheetPrimitive.Portal.Props) => (
23
- <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />
24
- );
25
-
26
- const SheetOverlay = ({ className, ...props }: SheetPrimitive.Backdrop.Props) => (
27
- <SheetPrimitive.Backdrop
28
- data-slot="sheet-overlay"
29
- className={cn(
30
- "fixed inset-0 z-50 bg-black/10 transition-opacity duration-150 data-ending-style:opacity-0 data-starting-style:opacity-0 supports-backdrop-filter:backdrop-blur-xs",
31
- className,
32
- )}
33
- {...props}
34
- />
35
- );
36
-
37
- const SheetContent = ({
38
- className,
39
- children,
40
- side = "right",
41
- showCloseButton = true,
42
- ...props
43
- }: SheetPrimitive.Popup.Props & {
44
- side?: "top" | "right" | "bottom" | "left";
45
- showCloseButton?: boolean;
46
- }) => (
47
- <SheetPortal>
48
- <SheetOverlay />
49
- <SheetPrimitive.Popup
50
- data-slot="sheet-content"
51
- data-side={side}
52
- className={cn(
53
- "fixed z-50 flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg transition duration-200 ease-in-out data-ending-style:opacity-0 data-starting-style:opacity-0 data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=bottom]:data-ending-style:translate-y-[2.5rem] data-[side=bottom]:data-starting-style:translate-y-[2.5rem] data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=left]:data-ending-style:translate-x-[-2.5rem] data-[side=left]:data-starting-style:translate-x-[-2.5rem] data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=right]:data-ending-style:translate-x-[2.5rem] data-[side=right]:data-starting-style:translate-x-[2.5rem] data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=top]:data-ending-style:translate-y-[-2.5rem] data-[side=top]:data-starting-style:translate-y-[-2.5rem] data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm",
54
- className,
55
- )}
56
- {...props}
57
- >
58
- {children}
59
- {showCloseButton && (
60
- <SheetPrimitive.Close
61
- data-slot="sheet-close"
62
- render={<Button variant="ghost" className="absolute top-3 right-3" size="icon-sm" />}
63
- >
64
- <XIcon />
65
- <span className="sr-only">Close</span>
66
- </SheetPrimitive.Close>
67
- )}
68
- </SheetPrimitive.Popup>
69
- </SheetPortal>
70
- );
71
-
72
- const SheetHeader = ({ className, ...props }: React.ComponentProps<"div">) => (
73
- <div data-slot="sheet-header" className={cn("flex flex-col gap-0.5 p-4", className)} {...props} />
74
- );
75
-
76
- const SheetFooter = ({ className, ...props }: React.ComponentProps<"div">) => (
77
- <div
78
- data-slot="sheet-footer"
79
- className={cn("mt-auto flex flex-col gap-2 p-4", className)}
80
- {...props}
81
- />
82
- );
83
-
84
- const SheetTitle = ({ className, ...props }: SheetPrimitive.Title.Props) => (
85
- <SheetPrimitive.Title
86
- data-slot="sheet-title"
87
- className={cn("font-heading text-base font-medium text-foreground", className)}
88
- {...props}
89
- />
90
- );
91
-
92
- const SheetDescription = ({ className, ...props }: SheetPrimitive.Description.Props) => (
93
- <SheetPrimitive.Description
94
- data-slot="sheet-description"
95
- className={cn("text-sm text-muted-foreground", className)}
96
- {...props}
97
- />
98
- );
99
-
100
- export {
101
- Sheet,
102
- SheetTrigger,
103
- SheetClose,
104
- SheetContent,
105
- SheetHeader,
106
- SheetFooter,
107
- SheetTitle,
108
- SheetDescription,
109
- };