agent-starter-pack 0.5.3__py3-none-any.whl → 0.6.0__py3-none-any.whl
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.
- {agent_starter_pack-0.5.3.dist-info → agent_starter_pack-0.6.0.dist-info}/METADATA +1 -1
- {agent_starter_pack-0.5.3.dist-info → agent_starter_pack-0.6.0.dist-info}/RECORD +59 -33
- agents/adk_base/notebooks/adk_app_testing.ipynb +1 -1
- agents/adk_gemini_fullstack/README.md +148 -0
- agents/adk_gemini_fullstack/app/agent.py +349 -0
- agents/adk_gemini_fullstack/app/config.py +11 -0
- agents/adk_gemini_fullstack/notebooks/adk_app_testing.ipynb +353 -0
- agents/adk_gemini_fullstack/notebooks/evaluating_adk_agent.ipynb +1528 -0
- agents/adk_gemini_fullstack/template/.templateconfig.yaml +37 -0
- agents/adk_gemini_fullstack/tests/integration/test_agent.py +58 -0
- agents/agentic_rag/notebooks/adk_app_testing.ipynb +1 -1
- src/base_template/Makefile +21 -2
- src/base_template/README.md +8 -3
- src/base_template/pyproject.toml +1 -4
- src/cli/commands/create.py +17 -10
- src/cli/utils/template.py +13 -10
- src/deployment_targets/cloud_run/app/server.py +7 -1
- src/deployment_targets/cloud_run/tests/integration/test_server_e2e.py +1 -1
- src/deployment_targets/cloud_run/tests/load_test/.results/.placeholder +321 -0
- src/frontends/adk_gemini_fullstack/frontend/components.json +21 -0
- src/frontends/adk_gemini_fullstack/frontend/eslint.config.js +28 -0
- src/frontends/adk_gemini_fullstack/frontend/index.html +12 -0
- src/frontends/adk_gemini_fullstack/frontend/package-lock.json +5829 -0
- src/frontends/adk_gemini_fullstack/frontend/package.json +46 -0
- src/frontends/adk_gemini_fullstack/frontend/public/vite.svg +1 -0
- src/frontends/adk_gemini_fullstack/frontend/src/App.tsx +565 -0
- src/frontends/adk_gemini_fullstack/frontend/src/components/ActivityTimeline.tsx +244 -0
- src/frontends/adk_gemini_fullstack/frontend/src/components/ChatMessagesView.tsx +419 -0
- src/frontends/adk_gemini_fullstack/frontend/src/components/InputForm.tsx +60 -0
- src/frontends/adk_gemini_fullstack/frontend/src/components/WelcomeScreen.tsx +56 -0
- src/frontends/adk_gemini_fullstack/frontend/src/components/ui/badge.tsx +46 -0
- src/frontends/adk_gemini_fullstack/frontend/src/components/ui/button.tsx +59 -0
- src/frontends/adk_gemini_fullstack/frontend/src/components/ui/card.tsx +92 -0
- src/frontends/adk_gemini_fullstack/frontend/src/components/ui/input.tsx +21 -0
- src/frontends/adk_gemini_fullstack/frontend/src/components/ui/scroll-area.tsx +56 -0
- src/frontends/adk_gemini_fullstack/frontend/src/components/ui/select.tsx +183 -0
- src/frontends/adk_gemini_fullstack/frontend/src/components/ui/tabs.tsx +64 -0
- src/frontends/adk_gemini_fullstack/frontend/src/components/ui/textarea.tsx +18 -0
- src/frontends/adk_gemini_fullstack/frontend/src/global.css +154 -0
- src/frontends/adk_gemini_fullstack/frontend/src/main.tsx +13 -0
- src/frontends/adk_gemini_fullstack/frontend/src/utils.ts +7 -0
- src/frontends/adk_gemini_fullstack/frontend/src/vite-env.d.ts +1 -0
- src/frontends/adk_gemini_fullstack/frontend/tsconfig.json +28 -0
- src/frontends/adk_gemini_fullstack/frontend/tsconfig.node.json +24 -0
- src/frontends/adk_gemini_fullstack/frontend/vite.config.ts +26 -0
- src/resources/locks/uv-adk_base-agent_engine.lock +24 -24
- src/resources/locks/uv-adk_base-cloud_run.lock +24 -24
- src/resources/locks/uv-adk_gemini_fullstack-agent_engine.lock +3217 -0
- src/resources/locks/uv-adk_gemini_fullstack-cloud_run.lock +3513 -0
- src/resources/locks/uv-agentic_rag-agent_engine.lock +88 -85
- src/resources/locks/uv-agentic_rag-cloud_run.lock +124 -119
- src/resources/locks/uv-crewai_coding_crew-agent_engine.lock +94 -91
- src/resources/locks/uv-crewai_coding_crew-cloud_run.lock +130 -125
- src/resources/locks/uv-langgraph_base_react-agent_engine.lock +91 -88
- src/resources/locks/uv-langgraph_base_react-cloud_run.lock +130 -125
- src/resources/locks/uv-live_api-cloud_run.lock +121 -116
- src/frontends/streamlit_adk/frontend/side_bar.py +0 -214
- src/frontends/streamlit_adk/frontend/streamlit_app.py +0 -314
- src/frontends/streamlit_adk/frontend/style/app_markdown.py +0 -37
- src/frontends/streamlit_adk/frontend/utils/chat_utils.py +0 -84
- src/frontends/streamlit_adk/frontend/utils/local_chat_history.py +0 -110
- src/frontends/streamlit_adk/frontend/utils/message_editing.py +0 -61
- src/frontends/streamlit_adk/frontend/utils/multimodal_utils.py +0 -223
- src/frontends/streamlit_adk/frontend/utils/stream_handler.py +0 -311
- src/frontends/streamlit_adk/frontend/utils/title_summary.py +0 -129
- {agent_starter_pack-0.5.3.dist-info → agent_starter_pack-0.6.0.dist-info}/WHEEL +0 -0
- {agent_starter_pack-0.5.3.dist-info → agent_starter_pack-0.6.0.dist-info}/entry_points.txt +0 -0
- {agent_starter_pack-0.5.3.dist-info → agent_starter_pack-0.6.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,60 @@
|
|
1
|
+
import { useState, useRef, useEffect } from "react";
|
2
|
+
import { Button } from "@/components/ui/button";
|
3
|
+
import { Textarea } from "@/components/ui/textarea";
|
4
|
+
import { Loader2, Send } from "lucide-react";
|
5
|
+
|
6
|
+
interface InputFormProps {
|
7
|
+
onSubmit: (query: string) => void;
|
8
|
+
isLoading: boolean;
|
9
|
+
context?: 'homepage' | 'chat'; // Add new context prop
|
10
|
+
}
|
11
|
+
|
12
|
+
export function InputForm({ onSubmit, isLoading, context = 'homepage' }: InputFormProps) {
|
13
|
+
const [inputValue, setInputValue] = useState("");
|
14
|
+
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
15
|
+
|
16
|
+
useEffect(() => {
|
17
|
+
if (textareaRef.current) {
|
18
|
+
textareaRef.current.focus();
|
19
|
+
}
|
20
|
+
}, []);
|
21
|
+
|
22
|
+
const handleSubmit = (e: React.FormEvent) => {
|
23
|
+
e.preventDefault();
|
24
|
+
if (inputValue.trim() && !isLoading) {
|
25
|
+
onSubmit(inputValue.trim());
|
26
|
+
setInputValue("");
|
27
|
+
}
|
28
|
+
};
|
29
|
+
|
30
|
+
const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
31
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
32
|
+
e.preventDefault();
|
33
|
+
handleSubmit(e);
|
34
|
+
}
|
35
|
+
};
|
36
|
+
|
37
|
+
const placeholderText =
|
38
|
+
context === 'chat'
|
39
|
+
? "Respond to the Agent, refine the plan, or type 'Looks good'..."
|
40
|
+
: "Ask me anything... e.g., A report on the latest Google I/O";
|
41
|
+
|
42
|
+
return (
|
43
|
+
<form onSubmit={handleSubmit} className="flex flex-col gap-2">
|
44
|
+
<div className="flex items-end space-x-2">
|
45
|
+
<Textarea
|
46
|
+
ref={textareaRef}
|
47
|
+
value={inputValue}
|
48
|
+
onChange={(e) => setInputValue(e.target.value)}
|
49
|
+
onKeyDown={handleKeyDown}
|
50
|
+
placeholder={placeholderText}
|
51
|
+
rows={1}
|
52
|
+
className="flex-1 resize-none pr-10 min-h-[40px]"
|
53
|
+
/>
|
54
|
+
<Button type="submit" size="icon" disabled={isLoading || !inputValue.trim()}>
|
55
|
+
{isLoading ? <Loader2 className="h-4 w-4 animate-spin" /> : <Send className="h-4 w-4" />}
|
56
|
+
</Button>
|
57
|
+
</div>
|
58
|
+
</form>
|
59
|
+
);
|
60
|
+
}
|
@@ -0,0 +1,56 @@
|
|
1
|
+
import { Button } from "@/components/ui/button";
|
2
|
+
import { InputForm } from "@/components/InputForm";
|
3
|
+
|
4
|
+
interface WelcomeScreenProps {
|
5
|
+
handleSubmit: (query: string) => void;
|
6
|
+
isLoading: boolean;
|
7
|
+
onCancel: () => void;
|
8
|
+
}
|
9
|
+
|
10
|
+
export function WelcomeScreen({
|
11
|
+
handleSubmit,
|
12
|
+
isLoading,
|
13
|
+
onCancel,
|
14
|
+
}: WelcomeScreenProps) {
|
15
|
+
return (
|
16
|
+
// This container fills the space provided by its parent layout (e.g., the left panel in a split view)
|
17
|
+
// and centers its content (the card) within itself.
|
18
|
+
<div className="flex-1 flex flex-col items-center justify-center p-4 overflow-hidden relative">
|
19
|
+
|
20
|
+
{/* The "Card" Container */}
|
21
|
+
{/* This div now holds the card's styling: background, blur, padding, border, shadow, and hover effect */}
|
22
|
+
<div className="w-full max-w-2xl z-10
|
23
|
+
bg-neutral-900/50 backdrop-blur-md
|
24
|
+
p-8 rounded-2xl border border-neutral-700
|
25
|
+
shadow-2xl shadow-black/60
|
26
|
+
transition-all duration-300 hover:border-neutral-600">
|
27
|
+
|
28
|
+
{/* Header section of the card */}
|
29
|
+
<div className="text-center space-y-4">
|
30
|
+
<h1 className="text-4xl font-bold text-white flex items-center justify-center gap-3">
|
31
|
+
✨ Gemini FullStack - ADK 🚀
|
32
|
+
</h1>
|
33
|
+
<p className="text-lg text-neutral-300 max-w-md mx-auto">
|
34
|
+
Turns your questions into comprehensive reports!
|
35
|
+
</p>
|
36
|
+
</div>
|
37
|
+
|
38
|
+
{/* Input form section of the card */}
|
39
|
+
<div className="mt-8">
|
40
|
+
<InputForm onSubmit={handleSubmit} isLoading={isLoading} context="homepage" />
|
41
|
+
{isLoading && (
|
42
|
+
<div className="mt-4 flex justify-center">
|
43
|
+
<Button
|
44
|
+
variant="outline"
|
45
|
+
onClick={onCancel}
|
46
|
+
className="text-red-400 hover:text-red-300 hover:bg-red-900/20 border-red-700/50" // Enhanced cancel button
|
47
|
+
>
|
48
|
+
Cancel
|
49
|
+
</Button>
|
50
|
+
</div>
|
51
|
+
)}
|
52
|
+
</div>
|
53
|
+
</div>
|
54
|
+
</div>
|
55
|
+
);
|
56
|
+
}
|
@@ -0,0 +1,46 @@
|
|
1
|
+
import * as React from "react"
|
2
|
+
import { Slot } from "@radix-ui/react-slot"
|
3
|
+
import { cva, type VariantProps } from "class-variance-authority"
|
4
|
+
|
5
|
+
import { cn } from "@/utils"
|
6
|
+
|
7
|
+
const badgeVariants = cva(
|
8
|
+
"inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
|
9
|
+
{
|
10
|
+
variants: {
|
11
|
+
variant: {
|
12
|
+
default:
|
13
|
+
"border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
|
14
|
+
secondary:
|
15
|
+
"border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
|
16
|
+
destructive:
|
17
|
+
"border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
18
|
+
outline:
|
19
|
+
"text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
|
20
|
+
},
|
21
|
+
},
|
22
|
+
defaultVariants: {
|
23
|
+
variant: "default",
|
24
|
+
},
|
25
|
+
}
|
26
|
+
)
|
27
|
+
|
28
|
+
function Badge({
|
29
|
+
className,
|
30
|
+
variant,
|
31
|
+
asChild = false,
|
32
|
+
...props
|
33
|
+
}: React.ComponentProps<"span"> &
|
34
|
+
VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
|
35
|
+
const Comp = asChild ? Slot : "span"
|
36
|
+
|
37
|
+
return (
|
38
|
+
<Comp
|
39
|
+
data-slot="badge"
|
40
|
+
className={cn(badgeVariants({ variant }), className)}
|
41
|
+
{...props}
|
42
|
+
/>
|
43
|
+
)
|
44
|
+
}
|
45
|
+
|
46
|
+
export { Badge, badgeVariants }
|
@@ -0,0 +1,59 @@
|
|
1
|
+
import * as React from "react"
|
2
|
+
import { Slot } from "@radix-ui/react-slot"
|
3
|
+
import { cva, type VariantProps } from "class-variance-authority"
|
4
|
+
|
5
|
+
import { cn } from "@/utils"
|
6
|
+
|
7
|
+
const buttonVariants = cva(
|
8
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
9
|
+
{
|
10
|
+
variants: {
|
11
|
+
variant: {
|
12
|
+
default:
|
13
|
+
"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
|
14
|
+
destructive:
|
15
|
+
"bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
16
|
+
outline:
|
17
|
+
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
|
18
|
+
secondary:
|
19
|
+
"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
|
20
|
+
ghost:
|
21
|
+
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
22
|
+
link: "text-primary underline-offset-4 hover:underline",
|
23
|
+
},
|
24
|
+
size: {
|
25
|
+
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
26
|
+
sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
|
27
|
+
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
|
28
|
+
icon: "size-9",
|
29
|
+
},
|
30
|
+
},
|
31
|
+
defaultVariants: {
|
32
|
+
variant: "default",
|
33
|
+
size: "default",
|
34
|
+
},
|
35
|
+
}
|
36
|
+
)
|
37
|
+
|
38
|
+
function Button({
|
39
|
+
className,
|
40
|
+
variant,
|
41
|
+
size,
|
42
|
+
asChild = false,
|
43
|
+
...props
|
44
|
+
}: React.ComponentProps<"button"> &
|
45
|
+
VariantProps<typeof buttonVariants> & {
|
46
|
+
asChild?: boolean
|
47
|
+
}) {
|
48
|
+
const Comp = asChild ? Slot : "button"
|
49
|
+
|
50
|
+
return (
|
51
|
+
<Comp
|
52
|
+
data-slot="button"
|
53
|
+
className={cn(buttonVariants({ variant, size, className }))}
|
54
|
+
{...props}
|
55
|
+
/>
|
56
|
+
)
|
57
|
+
}
|
58
|
+
|
59
|
+
export { Button, buttonVariants }
|
@@ -0,0 +1,92 @@
|
|
1
|
+
import * as React from "react"
|
2
|
+
|
3
|
+
import { cn } from "@/utils"
|
4
|
+
|
5
|
+
function Card({ className, ...props }: React.ComponentProps<"div">) {
|
6
|
+
return (
|
7
|
+
<div
|
8
|
+
data-slot="card"
|
9
|
+
className={cn(
|
10
|
+
"bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
|
11
|
+
className
|
12
|
+
)}
|
13
|
+
{...props}
|
14
|
+
/>
|
15
|
+
)
|
16
|
+
}
|
17
|
+
|
18
|
+
function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
|
19
|
+
return (
|
20
|
+
<div
|
21
|
+
data-slot="card-header"
|
22
|
+
className={cn(
|
23
|
+
"@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
|
24
|
+
className
|
25
|
+
)}
|
26
|
+
{...props}
|
27
|
+
/>
|
28
|
+
)
|
29
|
+
}
|
30
|
+
|
31
|
+
function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
|
32
|
+
return (
|
33
|
+
<div
|
34
|
+
data-slot="card-title"
|
35
|
+
className={cn("leading-none font-semibold", className)}
|
36
|
+
{...props}
|
37
|
+
/>
|
38
|
+
)
|
39
|
+
}
|
40
|
+
|
41
|
+
function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
|
42
|
+
return (
|
43
|
+
<div
|
44
|
+
data-slot="card-description"
|
45
|
+
className={cn("text-muted-foreground text-sm", className)}
|
46
|
+
{...props}
|
47
|
+
/>
|
48
|
+
)
|
49
|
+
}
|
50
|
+
|
51
|
+
function CardAction({ className, ...props }: React.ComponentProps<"div">) {
|
52
|
+
return (
|
53
|
+
<div
|
54
|
+
data-slot="card-action"
|
55
|
+
className={cn(
|
56
|
+
"col-start-2 row-span-2 row-start-1 self-start justify-self-end",
|
57
|
+
className
|
58
|
+
)}
|
59
|
+
{...props}
|
60
|
+
/>
|
61
|
+
)
|
62
|
+
}
|
63
|
+
|
64
|
+
function CardContent({ className, ...props }: React.ComponentProps<"div">) {
|
65
|
+
return (
|
66
|
+
<div
|
67
|
+
data-slot="card-content"
|
68
|
+
className={cn("px-6", className)}
|
69
|
+
{...props}
|
70
|
+
/>
|
71
|
+
)
|
72
|
+
}
|
73
|
+
|
74
|
+
function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
|
75
|
+
return (
|
76
|
+
<div
|
77
|
+
data-slot="card-footer"
|
78
|
+
className={cn("flex items-center px-6 [.border-t]:pt-6", className)}
|
79
|
+
{...props}
|
80
|
+
/>
|
81
|
+
)
|
82
|
+
}
|
83
|
+
|
84
|
+
export {
|
85
|
+
Card,
|
86
|
+
CardHeader,
|
87
|
+
CardFooter,
|
88
|
+
CardTitle,
|
89
|
+
CardAction,
|
90
|
+
CardDescription,
|
91
|
+
CardContent,
|
92
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import * as React from "react"
|
2
|
+
|
3
|
+
import { cn } from "@/utils"
|
4
|
+
|
5
|
+
function Input({ className, type, ...props }: React.ComponentProps<"input">) {
|
6
|
+
return (
|
7
|
+
<input
|
8
|
+
type={type}
|
9
|
+
data-slot="input"
|
10
|
+
className={cn(
|
11
|
+
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
12
|
+
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
13
|
+
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
14
|
+
className
|
15
|
+
)}
|
16
|
+
{...props}
|
17
|
+
/>
|
18
|
+
)
|
19
|
+
}
|
20
|
+
|
21
|
+
export { Input }
|
@@ -0,0 +1,56 @@
|
|
1
|
+
import * as React from "react"
|
2
|
+
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
|
3
|
+
|
4
|
+
import { cn } from "@/utils"
|
5
|
+
|
6
|
+
function ScrollArea({
|
7
|
+
className,
|
8
|
+
children,
|
9
|
+
...props
|
10
|
+
}: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {
|
11
|
+
return (
|
12
|
+
<ScrollAreaPrimitive.Root
|
13
|
+
data-slot="scroll-area"
|
14
|
+
className={cn("relative", className)}
|
15
|
+
{...props}
|
16
|
+
>
|
17
|
+
<ScrollAreaPrimitive.Viewport
|
18
|
+
data-slot="scroll-area-viewport"
|
19
|
+
className="focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1"
|
20
|
+
>
|
21
|
+
{children}
|
22
|
+
</ScrollAreaPrimitive.Viewport>
|
23
|
+
<ScrollBar />
|
24
|
+
<ScrollAreaPrimitive.Corner />
|
25
|
+
</ScrollAreaPrimitive.Root>
|
26
|
+
)
|
27
|
+
}
|
28
|
+
|
29
|
+
function ScrollBar({
|
30
|
+
className,
|
31
|
+
orientation = "vertical",
|
32
|
+
...props
|
33
|
+
}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {
|
34
|
+
return (
|
35
|
+
<ScrollAreaPrimitive.ScrollAreaScrollbar
|
36
|
+
data-slot="scroll-area-scrollbar"
|
37
|
+
orientation={orientation}
|
38
|
+
className={cn(
|
39
|
+
"flex touch-none p-px transition-colors select-none",
|
40
|
+
orientation === "vertical" &&
|
41
|
+
"h-full w-2.5 border-l border-l-transparent",
|
42
|
+
orientation === "horizontal" &&
|
43
|
+
"h-2.5 flex-col border-t border-t-transparent",
|
44
|
+
className
|
45
|
+
)}
|
46
|
+
{...props}
|
47
|
+
>
|
48
|
+
<ScrollAreaPrimitive.ScrollAreaThumb
|
49
|
+
data-slot="scroll-area-thumb"
|
50
|
+
className="bg-border relative flex-1 rounded-full"
|
51
|
+
/>
|
52
|
+
</ScrollAreaPrimitive.ScrollAreaScrollbar>
|
53
|
+
)
|
54
|
+
}
|
55
|
+
|
56
|
+
export { ScrollArea, ScrollBar }
|
@@ -0,0 +1,183 @@
|
|
1
|
+
import * as React from "react"
|
2
|
+
import * as SelectPrimitive from "@radix-ui/react-select"
|
3
|
+
import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react"
|
4
|
+
|
5
|
+
import { cn } from "@/utils"
|
6
|
+
|
7
|
+
function Select({
|
8
|
+
...props
|
9
|
+
}: React.ComponentProps<typeof SelectPrimitive.Root>) {
|
10
|
+
return <SelectPrimitive.Root data-slot="select" {...props} />
|
11
|
+
}
|
12
|
+
|
13
|
+
function SelectGroup({
|
14
|
+
...props
|
15
|
+
}: React.ComponentProps<typeof SelectPrimitive.Group>) {
|
16
|
+
return <SelectPrimitive.Group data-slot="select-group" {...props} />
|
17
|
+
}
|
18
|
+
|
19
|
+
function SelectValue({
|
20
|
+
...props
|
21
|
+
}: React.ComponentProps<typeof SelectPrimitive.Value>) {
|
22
|
+
return <SelectPrimitive.Value data-slot="select-value" {...props} />
|
23
|
+
}
|
24
|
+
|
25
|
+
function SelectTrigger({
|
26
|
+
className,
|
27
|
+
size = "default",
|
28
|
+
children,
|
29
|
+
...props
|
30
|
+
}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {
|
31
|
+
size?: "sm" | "default"
|
32
|
+
}) {
|
33
|
+
return (
|
34
|
+
<SelectPrimitive.Trigger
|
35
|
+
data-slot="select-trigger"
|
36
|
+
data-size={size}
|
37
|
+
className={cn(
|
38
|
+
"border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
39
|
+
className
|
40
|
+
)}
|
41
|
+
{...props}
|
42
|
+
>
|
43
|
+
{children}
|
44
|
+
<SelectPrimitive.Icon asChild>
|
45
|
+
<ChevronDownIcon className="size-4 opacity-50" />
|
46
|
+
</SelectPrimitive.Icon>
|
47
|
+
</SelectPrimitive.Trigger>
|
48
|
+
)
|
49
|
+
}
|
50
|
+
|
51
|
+
function SelectContent({
|
52
|
+
className,
|
53
|
+
children,
|
54
|
+
position = "popper",
|
55
|
+
...props
|
56
|
+
}: React.ComponentProps<typeof SelectPrimitive.Content>) {
|
57
|
+
return (
|
58
|
+
<SelectPrimitive.Portal>
|
59
|
+
<SelectPrimitive.Content
|
60
|
+
data-slot="select-content"
|
61
|
+
className={cn(
|
62
|
+
"bg-popover text-popover-foreground 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 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md",
|
63
|
+
position === "popper" &&
|
64
|
+
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
65
|
+
className
|
66
|
+
)}
|
67
|
+
position={position}
|
68
|
+
{...props}
|
69
|
+
>
|
70
|
+
<SelectScrollUpButton />
|
71
|
+
<SelectPrimitive.Viewport
|
72
|
+
className={cn(
|
73
|
+
"p-1",
|
74
|
+
position === "popper" &&
|
75
|
+
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1"
|
76
|
+
)}
|
77
|
+
>
|
78
|
+
{children}
|
79
|
+
</SelectPrimitive.Viewport>
|
80
|
+
<SelectScrollDownButton />
|
81
|
+
</SelectPrimitive.Content>
|
82
|
+
</SelectPrimitive.Portal>
|
83
|
+
)
|
84
|
+
}
|
85
|
+
|
86
|
+
function SelectLabel({
|
87
|
+
className,
|
88
|
+
...props
|
89
|
+
}: React.ComponentProps<typeof SelectPrimitive.Label>) {
|
90
|
+
return (
|
91
|
+
<SelectPrimitive.Label
|
92
|
+
data-slot="select-label"
|
93
|
+
className={cn("text-muted-foreground px-2 py-1.5 text-xs", className)}
|
94
|
+
{...props}
|
95
|
+
/>
|
96
|
+
)
|
97
|
+
}
|
98
|
+
|
99
|
+
function SelectItem({
|
100
|
+
className,
|
101
|
+
children,
|
102
|
+
...props
|
103
|
+
}: React.ComponentProps<typeof SelectPrimitive.Item>) {
|
104
|
+
return (
|
105
|
+
<SelectPrimitive.Item
|
106
|
+
data-slot="select-item"
|
107
|
+
className={cn(
|
108
|
+
"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
|
109
|
+
className
|
110
|
+
)}
|
111
|
+
{...props}
|
112
|
+
>
|
113
|
+
<span className="absolute right-2 flex size-3.5 items-center justify-center">
|
114
|
+
<SelectPrimitive.ItemIndicator>
|
115
|
+
<CheckIcon className="size-4" />
|
116
|
+
</SelectPrimitive.ItemIndicator>
|
117
|
+
</span>
|
118
|
+
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
|
119
|
+
</SelectPrimitive.Item>
|
120
|
+
)
|
121
|
+
}
|
122
|
+
|
123
|
+
function SelectSeparator({
|
124
|
+
className,
|
125
|
+
...props
|
126
|
+
}: React.ComponentProps<typeof SelectPrimitive.Separator>) {
|
127
|
+
return (
|
128
|
+
<SelectPrimitive.Separator
|
129
|
+
data-slot="select-separator"
|
130
|
+
className={cn("bg-border pointer-events-none -mx-1 my-1 h-px", className)}
|
131
|
+
{...props}
|
132
|
+
/>
|
133
|
+
)
|
134
|
+
}
|
135
|
+
|
136
|
+
function SelectScrollUpButton({
|
137
|
+
className,
|
138
|
+
...props
|
139
|
+
}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {
|
140
|
+
return (
|
141
|
+
<SelectPrimitive.ScrollUpButton
|
142
|
+
data-slot="select-scroll-up-button"
|
143
|
+
className={cn(
|
144
|
+
"flex cursor-default items-center justify-center py-1",
|
145
|
+
className
|
146
|
+
)}
|
147
|
+
{...props}
|
148
|
+
>
|
149
|
+
<ChevronUpIcon className="size-4" />
|
150
|
+
</SelectPrimitive.ScrollUpButton>
|
151
|
+
)
|
152
|
+
}
|
153
|
+
|
154
|
+
function SelectScrollDownButton({
|
155
|
+
className,
|
156
|
+
...props
|
157
|
+
}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {
|
158
|
+
return (
|
159
|
+
<SelectPrimitive.ScrollDownButton
|
160
|
+
data-slot="select-scroll-down-button"
|
161
|
+
className={cn(
|
162
|
+
"flex cursor-default items-center justify-center py-1",
|
163
|
+
className
|
164
|
+
)}
|
165
|
+
{...props}
|
166
|
+
>
|
167
|
+
<ChevronDownIcon className="size-4" />
|
168
|
+
</SelectPrimitive.ScrollDownButton>
|
169
|
+
)
|
170
|
+
}
|
171
|
+
|
172
|
+
export {
|
173
|
+
Select,
|
174
|
+
SelectContent,
|
175
|
+
SelectGroup,
|
176
|
+
SelectItem,
|
177
|
+
SelectLabel,
|
178
|
+
SelectScrollDownButton,
|
179
|
+
SelectScrollUpButton,
|
180
|
+
SelectSeparator,
|
181
|
+
SelectTrigger,
|
182
|
+
SelectValue,
|
183
|
+
}
|
@@ -0,0 +1,64 @@
|
|
1
|
+
import * as React from "react"
|
2
|
+
import * as TabsPrimitive from "@radix-ui/react-tabs"
|
3
|
+
|
4
|
+
import { cn } from "@/utils"
|
5
|
+
|
6
|
+
function Tabs({
|
7
|
+
className,
|
8
|
+
...props
|
9
|
+
}: React.ComponentProps<typeof TabsPrimitive.Root>) {
|
10
|
+
return (
|
11
|
+
<TabsPrimitive.Root
|
12
|
+
data-slot="tabs"
|
13
|
+
className={cn("flex flex-col gap-2", className)}
|
14
|
+
{...props}
|
15
|
+
/>
|
16
|
+
)
|
17
|
+
}
|
18
|
+
|
19
|
+
function TabsList({
|
20
|
+
className,
|
21
|
+
...props
|
22
|
+
}: React.ComponentProps<typeof TabsPrimitive.List>) {
|
23
|
+
return (
|
24
|
+
<TabsPrimitive.List
|
25
|
+
data-slot="tabs-list"
|
26
|
+
className={cn(
|
27
|
+
"bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]",
|
28
|
+
className
|
29
|
+
)}
|
30
|
+
{...props}
|
31
|
+
/>
|
32
|
+
)
|
33
|
+
}
|
34
|
+
|
35
|
+
function TabsTrigger({
|
36
|
+
className,
|
37
|
+
...props
|
38
|
+
}: React.ComponentProps<typeof TabsPrimitive.Trigger>) {
|
39
|
+
return (
|
40
|
+
<TabsPrimitive.Trigger
|
41
|
+
data-slot="tabs-trigger"
|
42
|
+
className={cn(
|
43
|
+
"data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
44
|
+
className
|
45
|
+
)}
|
46
|
+
{...props}
|
47
|
+
/>
|
48
|
+
)
|
49
|
+
}
|
50
|
+
|
51
|
+
function TabsContent({
|
52
|
+
className,
|
53
|
+
...props
|
54
|
+
}: React.ComponentProps<typeof TabsPrimitive.Content>) {
|
55
|
+
return (
|
56
|
+
<TabsPrimitive.Content
|
57
|
+
data-slot="tabs-content"
|
58
|
+
className={cn("flex-1 outline-none", className)}
|
59
|
+
{...props}
|
60
|
+
/>
|
61
|
+
)
|
62
|
+
}
|
63
|
+
|
64
|
+
export { Tabs, TabsList, TabsTrigger, TabsContent }
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import * as React from "react"
|
2
|
+
|
3
|
+
import { cn } from "@/utils"
|
4
|
+
|
5
|
+
function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
|
6
|
+
return (
|
7
|
+
<textarea
|
8
|
+
data-slot="textarea"
|
9
|
+
className={cn(
|
10
|
+
"border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
11
|
+
className
|
12
|
+
)}
|
13
|
+
{...props}
|
14
|
+
/>
|
15
|
+
)
|
16
|
+
}
|
17
|
+
|
18
|
+
export { Textarea }
|