eranet111 commited on
Commit ·
f438287
1
Parent(s): c692a27
Add function calling support and remove outdated processes
Browse filesImplement full OpenAPI function calling for all models with an agentic execution loop and prompt engineering fallback for unsupported models. Also, remove legacy processes.
Replit-Commit-Author: Agent
Replit-Commit-Session-Id: a225ab96-d6aa-42ce-a50b-aa844bc8db2b
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 2c19a569-11f7-45e9-9b74-8b2bb97a3a12
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/cbd1ae84-d682-4025-b26d-c56df1ac13a1/a225ab96-d6aa-42ce-a50b-aa844bc8db2b/jm4hNZf
Replit-Helium-Checkpoint-Created: true
This view is limited to 50 files because it contains too many changes. See raw diff
- ai-go/.gitattributes → .gitattributes +0 -0
- .replit +22 -1
- ai-go/Dockerfile → Dockerfile +0 -0
- ai-go/README.md → README.md +0 -0
- ai-go/main.go +0 -215
- artifacts/api-server/.replit-artifact/artifact.toml +0 -32
- artifacts/api-server/build.mjs +0 -126
- artifacts/api-server/package.json +0 -32
- artifacts/api-server/src/app.ts +0 -34
- artifacts/api-server/src/index.ts +0 -25
- artifacts/api-server/src/lib/.gitkeep +0 -0
- artifacts/api-server/src/lib/logger.ts +0 -20
- artifacts/api-server/src/middlewares/.gitkeep +0 -0
- artifacts/api-server/src/routes/health.ts +0 -11
- artifacts/api-server/src/routes/index.ts +0 -8
- artifacts/api-server/tsconfig.json +0 -17
- artifacts/mockup-sandbox/.replit-artifact/artifact.toml +0 -17
- artifacts/mockup-sandbox/components.json +0 -21
- artifacts/mockup-sandbox/index.html +0 -31
- artifacts/mockup-sandbox/mockupPreviewPlugin.ts +0 -180
- artifacts/mockup-sandbox/package.json +0 -74
- artifacts/mockup-sandbox/src/.generated/mockup-components.ts +0 -5
- artifacts/mockup-sandbox/src/App.tsx +0 -146
- artifacts/mockup-sandbox/src/components/ui/accordion.tsx +0 -55
- artifacts/mockup-sandbox/src/components/ui/alert-dialog.tsx +0 -139
- artifacts/mockup-sandbox/src/components/ui/alert.tsx +0 -59
- artifacts/mockup-sandbox/src/components/ui/aspect-ratio.tsx +0 -5
- artifacts/mockup-sandbox/src/components/ui/avatar.tsx +0 -50
- artifacts/mockup-sandbox/src/components/ui/badge.tsx +0 -37
- artifacts/mockup-sandbox/src/components/ui/breadcrumb.tsx +0 -115
- artifacts/mockup-sandbox/src/components/ui/button-group.tsx +0 -83
- artifacts/mockup-sandbox/src/components/ui/button.tsx +0 -58
- artifacts/mockup-sandbox/src/components/ui/calendar.tsx +0 -213
- artifacts/mockup-sandbox/src/components/ui/card.tsx +0 -76
- artifacts/mockup-sandbox/src/components/ui/carousel.tsx +0 -260
- artifacts/mockup-sandbox/src/components/ui/chart.tsx +0 -365
- artifacts/mockup-sandbox/src/components/ui/checkbox.tsx +0 -28
- artifacts/mockup-sandbox/src/components/ui/collapsible.tsx +0 -11
- artifacts/mockup-sandbox/src/components/ui/command.tsx +0 -153
- artifacts/mockup-sandbox/src/components/ui/context-menu.tsx +0 -198
- artifacts/mockup-sandbox/src/components/ui/dialog.tsx +0 -120
- artifacts/mockup-sandbox/src/components/ui/drawer.tsx +0 -116
- artifacts/mockup-sandbox/src/components/ui/dropdown-menu.tsx +0 -201
- artifacts/mockup-sandbox/src/components/ui/empty.tsx +0 -104
- artifacts/mockup-sandbox/src/components/ui/field.tsx +0 -244
- artifacts/mockup-sandbox/src/components/ui/form.tsx +0 -176
- artifacts/mockup-sandbox/src/components/ui/hover-card.tsx +0 -27
- artifacts/mockup-sandbox/src/components/ui/input-group.tsx +0 -165
- artifacts/mockup-sandbox/src/components/ui/input-otp.tsx +0 -69
- artifacts/mockup-sandbox/src/components/ui/input.tsx +0 -22
ai-go/.gitattributes → .gitattributes
RENAMED
|
File without changes
|
.replit
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
modules = ["nodejs-24"]
|
| 2 |
|
| 3 |
[[artifacts]]
|
| 4 |
id = "artifacts/api-server"
|
|
@@ -17,6 +17,27 @@ env = { "CI" = "true" }
|
|
| 17 |
[workflows]
|
| 18 |
runButton = "Project"
|
| 19 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
[agent]
|
| 21 |
stack = "PNPM_WORKSPACE"
|
| 22 |
expertMode = true
|
|
|
|
| 1 |
+
modules = ["nodejs-24", "go-1.23"]
|
| 2 |
|
| 3 |
[[artifacts]]
|
| 4 |
id = "artifacts/api-server"
|
|
|
|
| 17 |
[workflows]
|
| 18 |
runButton = "Project"
|
| 19 |
|
| 20 |
+
[[workflows.workflow]]
|
| 21 |
+
name = "Project"
|
| 22 |
+
mode = "parallel"
|
| 23 |
+
author = "agent"
|
| 24 |
+
|
| 25 |
+
[[workflows.workflow.tasks]]
|
| 26 |
+
task = "workflow.run"
|
| 27 |
+
args = "Start application"
|
| 28 |
+
|
| 29 |
+
[[workflows.workflow]]
|
| 30 |
+
name = "Start application"
|
| 31 |
+
author = "agent"
|
| 32 |
+
|
| 33 |
+
[[workflows.workflow.tasks]]
|
| 34 |
+
task = "shell.exec"
|
| 35 |
+
args = "go run ."
|
| 36 |
+
waitForPort = 8080
|
| 37 |
+
|
| 38 |
+
[workflows.workflow.metadata]
|
| 39 |
+
outputType = "console"
|
| 40 |
+
|
| 41 |
[agent]
|
| 42 |
stack = "PNPM_WORKSPACE"
|
| 43 |
expertMode = true
|
ai-go/Dockerfile → Dockerfile
RENAMED
|
File without changes
|
ai-go/README.md → README.md
RENAMED
|
File without changes
|
ai-go/main.go
DELETED
|
@@ -1,215 +0,0 @@
|
|
| 1 |
-
package main
|
| 2 |
-
|
| 3 |
-
import (
|
| 4 |
-
"bufio"
|
| 5 |
-
"bytes"
|
| 6 |
-
"encoding/json"
|
| 7 |
-
"fmt"
|
| 8 |
-
"log"
|
| 9 |
-
"net/http"
|
| 10 |
-
"sort"
|
| 11 |
-
"strings"
|
| 12 |
-
)
|
| 13 |
-
|
| 14 |
-
const (
|
| 15 |
-
NvidiaBaseURL = "https://integrate.api.nvidia.com/v1"
|
| 16 |
-
// Hardcodowany klucz
|
| 17 |
-
NvidiaAPIKey = "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"
|
| 18 |
-
GatewayAPIKey = "connect"
|
| 19 |
-
)
|
| 20 |
-
|
| 21 |
-
var modelAliases = map[string]string{
|
| 22 |
-
"Bielik-11b": "speakleash/bielik-11b-v2.6-instruct",
|
| 23 |
-
"GLM-4.7": "z-ai/glm4.7",
|
| 24 |
-
"Mistral-Small-4": "mistralai/mistral-small-4-119b-2603",
|
| 25 |
-
"DeepSeek-V3.1": "deepseek-ai/deepseek-v3.1",
|
| 26 |
-
"Kimi-K2": "moonshotai/kimi-k2-instruct",
|
| 27 |
-
}
|
| 28 |
-
|
| 29 |
-
// --- STRUKTURY ---
|
| 30 |
-
|
| 31 |
-
type Message struct {
|
| 32 |
-
Role string `json:"role"`
|
| 33 |
-
Content interface{} `json:"content"`
|
| 34 |
-
ToolCallID string `json:"tool_call_id,omitempty"`
|
| 35 |
-
ToolCalls interface{} `json:"tool_calls,omitempty"`
|
| 36 |
-
Name string `json:"name,omitempty"`
|
| 37 |
-
}
|
| 38 |
-
|
| 39 |
-
type ChatRequest struct {
|
| 40 |
-
Model string `json:"model"`
|
| 41 |
-
Messages []Message `json:"messages"`
|
| 42 |
-
Stream *bool `json:"stream,omitempty"`
|
| 43 |
-
Tools []interface{} `json:"tools,omitempty"`
|
| 44 |
-
ToolChoice interface{} `json:"tool_choice,omitempty"`
|
| 45 |
-
Temperature *float64 `json:"temperature,omitempty"`
|
| 46 |
-
MaxTokens *int `json:"max_tokens,omitempty"`
|
| 47 |
-
}
|
| 48 |
-
|
| 49 |
-
type AccumToolCall struct {
|
| 50 |
-
Index int
|
| 51 |
-
ID string
|
| 52 |
-
Name string
|
| 53 |
-
Args string
|
| 54 |
-
}
|
| 55 |
-
|
| 56 |
-
// --- LOGIKA ---
|
| 57 |
-
|
| 58 |
-
func resolveModel(requested string) string {
|
| 59 |
-
if full, ok := modelAliases[requested]; ok { return full }
|
| 60 |
-
return requested
|
| 61 |
-
}
|
| 62 |
-
|
| 63 |
-
func injectSystemPrompt(messages []Message, modelID string) []Message {
|
| 64 |
-
prompt, ok := systemPrompts[modelID]
|
| 65 |
-
if !ok || prompt == "" { return messages }
|
| 66 |
-
if len(messages) > 0 && messages[0].Role == "system" { return messages }
|
| 67 |
-
return append([]Message{{Role: "system", Content: prompt}}, messages...)
|
| 68 |
-
}
|
| 69 |
-
|
| 70 |
-
func handleChat(w http.ResponseWriter, r *http.Request) {
|
| 71 |
-
if r.Method == http.MethodOptions {
|
| 72 |
-
w.Header().Set("Access-Control-Allow-Origin", "*")
|
| 73 |
-
w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
|
| 74 |
-
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization, x-api-key")
|
| 75 |
-
w.WriteHeader(http.StatusNoContent)
|
| 76 |
-
return
|
| 77 |
-
}
|
| 78 |
-
|
| 79 |
-
auth := r.Header.Get("Authorization")
|
| 80 |
-
if !strings.Contains(auth, GatewayAPIKey) && r.Header.Get("x-api-key") != GatewayAPIKey {
|
| 81 |
-
http.Error(w, "Unauthorized", http.StatusUnauthorized); return
|
| 82 |
-
}
|
| 83 |
-
|
| 84 |
-
var req ChatRequest
|
| 85 |
-
json.NewDecoder(r.Body).Decode(&req)
|
| 86 |
-
|
| 87 |
-
modelID := resolveModel(req.Model)
|
| 88 |
-
upstreamPayload := map[string]interface{}{
|
| 89 |
-
"model": modelID,
|
| 90 |
-
"messages": injectSystemPrompt(req.Messages, modelID),
|
| 91 |
-
"stream": true,
|
| 92 |
-
}
|
| 93 |
-
if req.Temperature != nil { upstreamPayload["temperature"] = *req.Temperature }
|
| 94 |
-
if req.MaxTokens != nil { upstreamPayload["max_tokens"] = *req.MaxTokens }
|
| 95 |
-
if len(req.Tools) > 0 {
|
| 96 |
-
upstreamPayload["tools"] = req.Tools
|
| 97 |
-
upstreamPayload["tool_choice"] = req.ToolChoice
|
| 98 |
-
}
|
| 99 |
-
|
| 100 |
-
body, _ := json.Marshal(upstreamPayload)
|
| 101 |
-
upstreamReq, _ := http.NewRequest("POST", NvidiaBaseURL+"/chat/completions", bytes.NewReader(body))
|
| 102 |
-
upstreamReq.Header.Set("Content-Type", "application/json")
|
| 103 |
-
upstreamReq.Header.Set("Authorization", "Bearer "+NvidiaAPIKey)
|
| 104 |
-
|
| 105 |
-
resp, err := http.DefaultClient.Do(upstreamReq)
|
| 106 |
-
if err != nil { http.Error(w, err.Error(), 502); return }
|
| 107 |
-
defer resp.Body.Close()
|
| 108 |
-
|
| 109 |
-
w.Header().Set("Content-Type", "text/event-stream")
|
| 110 |
-
w.Header().Set("Access-Control-Allow-Origin", "*")
|
| 111 |
-
w.Header().Set("X-Accel-Buffering", "no")
|
| 112 |
-
|
| 113 |
-
flusher, _ := w.(http.Flusher)
|
| 114 |
-
scanner := bufio.NewScanner(resp.Body)
|
| 115 |
-
accum := make(map[int]*AccumToolCall)
|
| 116 |
-
firstChunkSent := false
|
| 117 |
-
|
| 118 |
-
for scanner.Scan() {
|
| 119 |
-
line := scanner.Text()
|
| 120 |
-
if !strings.HasPrefix(line, "data: ") || line == "data: [DONE]" {
|
| 121 |
-
fmt.Fprint(w, line+"\n\n"); if flusher != nil { flusher.Flush() }; continue
|
| 122 |
-
}
|
| 123 |
-
|
| 124 |
-
var chunk map[string]interface{}
|
| 125 |
-
if err := json.Unmarshal([]byte(strings.TrimPrefix(line, "data: ")), &chunk); err != nil {
|
| 126 |
-
continue
|
| 127 |
-
}
|
| 128 |
-
|
| 129 |
-
choices, ok := chunk["choices"].([]interface{})
|
| 130 |
-
if !ok || len(choices) == 0 { continue }
|
| 131 |
-
|
| 132 |
-
choice := choices[0].(map[string]interface{})
|
| 133 |
-
delta := choice["delta"].(map[string]interface{})
|
| 134 |
-
finishReason := choice["finish_reason"]
|
| 135 |
-
|
| 136 |
-
if tcs, ok := delta["tool_calls"].([]interface{}); ok {
|
| 137 |
-
for _, tcVal := range tcs {
|
| 138 |
-
tc := tcVal.(map[string]interface{})
|
| 139 |
-
idx := int(tc["index"].(float64))
|
| 140 |
-
acc, exists := accum[idx]
|
| 141 |
-
if !exists {
|
| 142 |
-
acc = &AccumToolCall{Index: idx}
|
| 143 |
-
if id, ok := tc["id"].(string); ok { acc.ID = id }
|
| 144 |
-
accum[idx] = acc
|
| 145 |
-
}
|
| 146 |
-
if fn, ok := tc["function"].(map[string]interface{}); ok {
|
| 147 |
-
if name, ok := fn["name"].(string); ok { acc.Name += name }
|
| 148 |
-
if args, ok := fn["arguments"].(string); ok { acc.Args += args }
|
| 149 |
-
}
|
| 150 |
-
}
|
| 151 |
-
continue
|
| 152 |
-
}
|
| 153 |
-
|
| 154 |
-
if (finishReason == "tool_calls" || finishReason == "function_call") && len(accum) > 0 {
|
| 155 |
-
var keys []int
|
| 156 |
-
for k := range accum { keys = append(keys, k) }
|
| 157 |
-
sort.Ints(keys)
|
| 158 |
-
|
| 159 |
-
finalTools := []map[string]interface{}{}
|
| 160 |
-
for _, k := range keys {
|
| 161 |
-
a := accum[k]
|
| 162 |
-
finalTools = append(finalTools, map[string]interface{}{
|
| 163 |
-
"index": a.Index, "id": a.ID, "type": "function",
|
| 164 |
-
"function": map[string]interface{}{"name": a.Name, "arguments": a.Args},
|
| 165 |
-
})
|
| 166 |
-
}
|
| 167 |
-
|
| 168 |
-
response := map[string]interface{}{
|
| 169 |
-
"id": chunk["id"], "object": "chat.completion.chunk", "created": chunk["created"],
|
| 170 |
-
"model": req.Model,
|
| 171 |
-
"choices": []map[string]interface{}{{
|
| 172 |
-
"index": 0,
|
| 173 |
-
"delta": map[string]interface{}{"role": "assistant", "tool_calls": finalTools},
|
| 174 |
-
"finish_reason": "tool_calls",
|
| 175 |
-
}},
|
| 176 |
-
}
|
| 177 |
-
jsonBytes, _ := json.Marshal(response)
|
| 178 |
-
fmt.Fprintf(w, "data: %s\n\n", string(jsonBytes))
|
| 179 |
-
if flusher != nil { flusher.Flush() }
|
| 180 |
-
accum = make(map[int]*AccumToolCall)
|
| 181 |
-
continue
|
| 182 |
-
}
|
| 183 |
-
|
| 184 |
-
if !firstChunkSent && delta["content"] != nil {
|
| 185 |
-
delta["role"] = "assistant"
|
| 186 |
-
firstChunkSent = true
|
| 187 |
-
}
|
| 188 |
-
|
| 189 |
-
if delta["content"] == nil && delta["tool_calls"] == nil && finishReason == nil {
|
| 190 |
-
continue
|
| 191 |
-
}
|
| 192 |
-
|
| 193 |
-
out, _ := json.Marshal(chunk)
|
| 194 |
-
fmt.Fprintf(w, "data: %s\n\n", string(out))
|
| 195 |
-
if flusher != nil { flusher.Flush() }
|
| 196 |
-
}
|
| 197 |
-
}
|
| 198 |
-
|
| 199 |
-
func handleModels(w http.ResponseWriter, r *http.Request) {
|
| 200 |
-
w.Header().Set("Content-Type", "application/json")
|
| 201 |
-
w.Header().Set("Access-Control-Allow-Origin", "*")
|
| 202 |
-
var data []map[string]interface{}
|
| 203 |
-
for alias := range modelAliases {
|
| 204 |
-
data = append(data, map[string]interface{}{"id": alias, "object": "model", "owned_by": "nvidia"})
|
| 205 |
-
}
|
| 206 |
-
json.NewEncoder(w).Encode(map[string]interface{}{"object": "list", "data": data})
|
| 207 |
-
}
|
| 208 |
-
|
| 209 |
-
func main() {
|
| 210 |
-
mux := http.NewServeMux()
|
| 211 |
-
mux.HandleFunc("/v1/chat/completions", handleChat)
|
| 212 |
-
mux.HandleFunc("/v1/models", handleModels)
|
| 213 |
-
log.Printf("Gateway running on :7860")
|
| 214 |
-
http.ListenAndServe(":7860", mux)
|
| 215 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/api-server/.replit-artifact/artifact.toml
DELETED
|
@@ -1,32 +0,0 @@
|
|
| 1 |
-
kind = "api"
|
| 2 |
-
previewPath = "/api" # TODO - should be excluded from preview in the first place
|
| 3 |
-
title = "API Server"
|
| 4 |
-
version = "1.0.0"
|
| 5 |
-
id = "3B4_FFSkEVBkAeYMFRJ2e"
|
| 6 |
-
|
| 7 |
-
[[services]]
|
| 8 |
-
localPort = 8080
|
| 9 |
-
name = "API Server"
|
| 10 |
-
paths = ["/api"]
|
| 11 |
-
|
| 12 |
-
[services.development]
|
| 13 |
-
run = "pnpm --filter @workspace/api-server run dev"
|
| 14 |
-
|
| 15 |
-
[services.production]
|
| 16 |
-
|
| 17 |
-
[services.production.build]
|
| 18 |
-
args = ["pnpm", "--filter", "@workspace/api-server", "run", "build"]
|
| 19 |
-
|
| 20 |
-
[services.production.build.env]
|
| 21 |
-
NODE_ENV = "production"
|
| 22 |
-
|
| 23 |
-
[services.production.run]
|
| 24 |
-
# we don't run through pnpm to make startup faster in production
|
| 25 |
-
args = ["node", "--enable-source-maps", "artifacts/api-server/dist/index.mjs"]
|
| 26 |
-
|
| 27 |
-
[services.production.run.env]
|
| 28 |
-
PORT = "8080"
|
| 29 |
-
NODE_ENV = "production"
|
| 30 |
-
|
| 31 |
-
[services.production.health.startup]
|
| 32 |
-
path = "/api/healthz"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/api-server/build.mjs
DELETED
|
@@ -1,126 +0,0 @@
|
|
| 1 |
-
import { createRequire } from "node:module";
|
| 2 |
-
import path from "node:path";
|
| 3 |
-
import { fileURLToPath } from "node:url";
|
| 4 |
-
import { build as esbuild } from "esbuild";
|
| 5 |
-
import esbuildPluginPino from "esbuild-plugin-pino";
|
| 6 |
-
import { rm } from "node:fs/promises";
|
| 7 |
-
|
| 8 |
-
// Plugins (e.g. 'esbuild-plugin-pino') may use `require` to resolve dependencies
|
| 9 |
-
globalThis.require = createRequire(import.meta.url);
|
| 10 |
-
|
| 11 |
-
const artifactDir = path.dirname(fileURLToPath(import.meta.url));
|
| 12 |
-
|
| 13 |
-
async function buildAll() {
|
| 14 |
-
const distDir = path.resolve(artifactDir, "dist");
|
| 15 |
-
await rm(distDir, { recursive: true, force: true });
|
| 16 |
-
|
| 17 |
-
await esbuild({
|
| 18 |
-
entryPoints: [path.resolve(artifactDir, "src/index.ts")],
|
| 19 |
-
platform: "node",
|
| 20 |
-
bundle: true,
|
| 21 |
-
format: "esm",
|
| 22 |
-
outdir: distDir,
|
| 23 |
-
outExtension: { ".js": ".mjs" },
|
| 24 |
-
logLevel: "info",
|
| 25 |
-
// Some packages may not be bundleable, so we externalize them, we can add more here as needed.
|
| 26 |
-
// Some of the packages below may not be imported or installed, but we're adding them in case they are in the future.
|
| 27 |
-
// Examples of unbundleable packages:
|
| 28 |
-
// - uses native modules and loads them dynamically (e.g. sharp)
|
| 29 |
-
// - use path traversal to read files (e.g. @google-cloud/secret-manager loads sibling .proto files)
|
| 30 |
-
external: [
|
| 31 |
-
"*.node",
|
| 32 |
-
"sharp",
|
| 33 |
-
"better-sqlite3",
|
| 34 |
-
"sqlite3",
|
| 35 |
-
"canvas",
|
| 36 |
-
"bcrypt",
|
| 37 |
-
"argon2",
|
| 38 |
-
"fsevents",
|
| 39 |
-
"re2",
|
| 40 |
-
"farmhash",
|
| 41 |
-
"xxhash-addon",
|
| 42 |
-
"bufferutil",
|
| 43 |
-
"utf-8-validate",
|
| 44 |
-
"ssh2",
|
| 45 |
-
"cpu-features",
|
| 46 |
-
"dtrace-provider",
|
| 47 |
-
"isolated-vm",
|
| 48 |
-
"lightningcss",
|
| 49 |
-
"pg-native",
|
| 50 |
-
"oracledb",
|
| 51 |
-
"mongodb-client-encryption",
|
| 52 |
-
"nodemailer",
|
| 53 |
-
"handlebars",
|
| 54 |
-
"knex",
|
| 55 |
-
"typeorm",
|
| 56 |
-
"protobufjs",
|
| 57 |
-
"onnxruntime-node",
|
| 58 |
-
"@tensorflow/*",
|
| 59 |
-
"@prisma/client",
|
| 60 |
-
"@mikro-orm/*",
|
| 61 |
-
"@grpc/*",
|
| 62 |
-
"@swc/*",
|
| 63 |
-
"@aws-sdk/*",
|
| 64 |
-
"@azure/*",
|
| 65 |
-
"@opentelemetry/*",
|
| 66 |
-
"@google-cloud/*",
|
| 67 |
-
"@google/*",
|
| 68 |
-
"googleapis",
|
| 69 |
-
"firebase-admin",
|
| 70 |
-
"@parcel/watcher",
|
| 71 |
-
"@sentry/profiling-node",
|
| 72 |
-
"@tree-sitter/*",
|
| 73 |
-
"aws-sdk",
|
| 74 |
-
"classic-level",
|
| 75 |
-
"dd-trace",
|
| 76 |
-
"ffi-napi",
|
| 77 |
-
"grpc",
|
| 78 |
-
"hiredis",
|
| 79 |
-
"kerberos",
|
| 80 |
-
"leveldown",
|
| 81 |
-
"miniflare",
|
| 82 |
-
"mysql2",
|
| 83 |
-
"newrelic",
|
| 84 |
-
"odbc",
|
| 85 |
-
"piscina",
|
| 86 |
-
"realm",
|
| 87 |
-
"ref-napi",
|
| 88 |
-
"rocksdb",
|
| 89 |
-
"sass-embedded",
|
| 90 |
-
"sequelize",
|
| 91 |
-
"serialport",
|
| 92 |
-
"snappy",
|
| 93 |
-
"tinypool",
|
| 94 |
-
"usb",
|
| 95 |
-
"workerd",
|
| 96 |
-
"wrangler",
|
| 97 |
-
"zeromq",
|
| 98 |
-
"zeromq-prebuilt",
|
| 99 |
-
"playwright",
|
| 100 |
-
"puppeteer",
|
| 101 |
-
"puppeteer-core",
|
| 102 |
-
"electron",
|
| 103 |
-
],
|
| 104 |
-
sourcemap: "linked",
|
| 105 |
-
plugins: [
|
| 106 |
-
// pino relies on workers to handle logging, instead of externalizing it we use a plugin to handle it
|
| 107 |
-
esbuildPluginPino({ transports: ["pino-pretty"] })
|
| 108 |
-
],
|
| 109 |
-
// Make sure packages that are cjs only (e.g. express) but are bundled continue to work in our esm output file
|
| 110 |
-
banner: {
|
| 111 |
-
js: `import { createRequire as __bannerCrReq } from 'node:module';
|
| 112 |
-
import __bannerPath from 'node:path';
|
| 113 |
-
import __bannerUrl from 'node:url';
|
| 114 |
-
|
| 115 |
-
globalThis.require = __bannerCrReq(import.meta.url);
|
| 116 |
-
globalThis.__filename = __bannerUrl.fileURLToPath(import.meta.url);
|
| 117 |
-
globalThis.__dirname = __bannerPath.dirname(globalThis.__filename);
|
| 118 |
-
`,
|
| 119 |
-
},
|
| 120 |
-
});
|
| 121 |
-
}
|
| 122 |
-
|
| 123 |
-
buildAll().catch((err) => {
|
| 124 |
-
console.error(err);
|
| 125 |
-
process.exit(1);
|
| 126 |
-
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/api-server/package.json
DELETED
|
@@ -1,32 +0,0 @@
|
|
| 1 |
-
{
|
| 2 |
-
"name": "@workspace/api-server",
|
| 3 |
-
"version": "0.0.0",
|
| 4 |
-
"private": true,
|
| 5 |
-
"type": "module",
|
| 6 |
-
"scripts": {
|
| 7 |
-
"dev": "export NODE_ENV=development && pnpm run build && pnpm run start",
|
| 8 |
-
"build": "node ./build.mjs",
|
| 9 |
-
"start": "node --enable-source-maps ./dist/index.mjs",
|
| 10 |
-
"typecheck": "tsc -p tsconfig.json --noEmit"
|
| 11 |
-
},
|
| 12 |
-
"dependencies": {
|
| 13 |
-
"@workspace/api-zod": "workspace:*",
|
| 14 |
-
"@workspace/db": "workspace:*",
|
| 15 |
-
"cookie-parser": "^1.4.7",
|
| 16 |
-
"cors": "^2",
|
| 17 |
-
"drizzle-orm": "catalog:",
|
| 18 |
-
"express": "^5",
|
| 19 |
-
"pino": "^9",
|
| 20 |
-
"pino-http": "^10"
|
| 21 |
-
},
|
| 22 |
-
"devDependencies": {
|
| 23 |
-
"@types/cookie-parser": "^1.4.10",
|
| 24 |
-
"@types/cors": "^2.8.19",
|
| 25 |
-
"@types/express": "^5.0.6",
|
| 26 |
-
"@types/node": "catalog:",
|
| 27 |
-
"esbuild": "^0.27.3",
|
| 28 |
-
"esbuild-plugin-pino": "^2.3.3",
|
| 29 |
-
"pino-pretty": "^13",
|
| 30 |
-
"thread-stream": "3.1.0"
|
| 31 |
-
}
|
| 32 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/api-server/src/app.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
| 1 |
-
import express, { type Express } from "express";
|
| 2 |
-
import cors from "cors";
|
| 3 |
-
import pinoHttp from "pino-http";
|
| 4 |
-
import router from "./routes";
|
| 5 |
-
import { logger } from "./lib/logger";
|
| 6 |
-
|
| 7 |
-
const app: Express = express();
|
| 8 |
-
|
| 9 |
-
app.use(
|
| 10 |
-
pinoHttp({
|
| 11 |
-
logger,
|
| 12 |
-
serializers: {
|
| 13 |
-
req(req) {
|
| 14 |
-
return {
|
| 15 |
-
id: req.id,
|
| 16 |
-
method: req.method,
|
| 17 |
-
url: req.url?.split("?")[0],
|
| 18 |
-
};
|
| 19 |
-
},
|
| 20 |
-
res(res) {
|
| 21 |
-
return {
|
| 22 |
-
statusCode: res.statusCode,
|
| 23 |
-
};
|
| 24 |
-
},
|
| 25 |
-
},
|
| 26 |
-
}),
|
| 27 |
-
);
|
| 28 |
-
app.use(cors());
|
| 29 |
-
app.use(express.json());
|
| 30 |
-
app.use(express.urlencoded({ extended: true }));
|
| 31 |
-
|
| 32 |
-
app.use("/api", router);
|
| 33 |
-
|
| 34 |
-
export default app;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/api-server/src/index.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
| 1 |
-
import app from "./app";
|
| 2 |
-
import { logger } from "./lib/logger";
|
| 3 |
-
|
| 4 |
-
const rawPort = process.env["PORT"];
|
| 5 |
-
|
| 6 |
-
if (!rawPort) {
|
| 7 |
-
throw new Error(
|
| 8 |
-
"PORT environment variable is required but was not provided.",
|
| 9 |
-
);
|
| 10 |
-
}
|
| 11 |
-
|
| 12 |
-
const port = Number(rawPort);
|
| 13 |
-
|
| 14 |
-
if (Number.isNaN(port) || port <= 0) {
|
| 15 |
-
throw new Error(`Invalid PORT value: "${rawPort}"`);
|
| 16 |
-
}
|
| 17 |
-
|
| 18 |
-
app.listen(port, (err) => {
|
| 19 |
-
if (err) {
|
| 20 |
-
logger.error({ err }, "Error listening on port");
|
| 21 |
-
process.exit(1);
|
| 22 |
-
}
|
| 23 |
-
|
| 24 |
-
logger.info({ port }, "Server listening");
|
| 25 |
-
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/api-server/src/lib/.gitkeep
DELETED
|
File without changes
|
artifacts/api-server/src/lib/logger.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
| 1 |
-
import pino from "pino";
|
| 2 |
-
|
| 3 |
-
const isProduction = process.env.NODE_ENV === "production";
|
| 4 |
-
|
| 5 |
-
export const logger = pino({
|
| 6 |
-
level: process.env.LOG_LEVEL ?? "info",
|
| 7 |
-
redact: [
|
| 8 |
-
"req.headers.authorization",
|
| 9 |
-
"req.headers.cookie",
|
| 10 |
-
"res.headers['set-cookie']",
|
| 11 |
-
],
|
| 12 |
-
...(isProduction
|
| 13 |
-
? {}
|
| 14 |
-
: {
|
| 15 |
-
transport: {
|
| 16 |
-
target: "pino-pretty",
|
| 17 |
-
options: { colorize: true },
|
| 18 |
-
},
|
| 19 |
-
}),
|
| 20 |
-
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/api-server/src/middlewares/.gitkeep
DELETED
|
File without changes
|
artifacts/api-server/src/routes/health.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
| 1 |
-
import { Router, type IRouter } from "express";
|
| 2 |
-
import { HealthCheckResponse } from "@workspace/api-zod";
|
| 3 |
-
|
| 4 |
-
const router: IRouter = Router();
|
| 5 |
-
|
| 6 |
-
router.get("/healthz", (_req, res) => {
|
| 7 |
-
const data = HealthCheckResponse.parse({ status: "ok" });
|
| 8 |
-
res.json(data);
|
| 9 |
-
});
|
| 10 |
-
|
| 11 |
-
export default router;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/api-server/src/routes/index.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
| 1 |
-
import { Router, type IRouter } from "express";
|
| 2 |
-
import healthRouter from "./health";
|
| 3 |
-
|
| 4 |
-
const router: IRouter = Router();
|
| 5 |
-
|
| 6 |
-
router.use(healthRouter);
|
| 7 |
-
|
| 8 |
-
export default router;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/api-server/tsconfig.json
DELETED
|
@@ -1,17 +0,0 @@
|
|
| 1 |
-
{
|
| 2 |
-
"extends": "../../tsconfig.base.json",
|
| 3 |
-
"compilerOptions": {
|
| 4 |
-
"outDir": "dist",
|
| 5 |
-
"rootDir": "src",
|
| 6 |
-
"types": ["node"]
|
| 7 |
-
},
|
| 8 |
-
"include": ["src"],
|
| 9 |
-
"references": [
|
| 10 |
-
{
|
| 11 |
-
"path": "../../lib/db"
|
| 12 |
-
},
|
| 13 |
-
{
|
| 14 |
-
"path": "../../lib/api-zod"
|
| 15 |
-
}
|
| 16 |
-
]
|
| 17 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/.replit-artifact/artifact.toml
DELETED
|
@@ -1,17 +0,0 @@
|
|
| 1 |
-
kind = "design"
|
| 2 |
-
previewPath = "/__mockup"
|
| 3 |
-
title = "Component Preview Server"
|
| 4 |
-
version = "1.0.0"
|
| 5 |
-
id = "XegfDyZt7HqfW2Bb8Ghoy"
|
| 6 |
-
|
| 7 |
-
[[services]]
|
| 8 |
-
localPort = 8081
|
| 9 |
-
name = "Component Preview Server"
|
| 10 |
-
paths = ["/__mockup"]
|
| 11 |
-
|
| 12 |
-
[services.env]
|
| 13 |
-
PORT = "8081"
|
| 14 |
-
BASE_PATH = "/__mockup"
|
| 15 |
-
|
| 16 |
-
[services.development]
|
| 17 |
-
run = "pnpm --filter @workspace/mockup-sandbox run dev"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/components.json
DELETED
|
@@ -1,21 +0,0 @@
|
|
| 1 |
-
{
|
| 2 |
-
"$schema": "https://ui.shadcn.com/schema.json",
|
| 3 |
-
"style": "new-york",
|
| 4 |
-
"rsc": false,
|
| 5 |
-
"tsx": true,
|
| 6 |
-
"tailwind": {
|
| 7 |
-
"config": "",
|
| 8 |
-
"css": "src/index.css",
|
| 9 |
-
"baseColor": "neutral",
|
| 10 |
-
"cssVariables": true,
|
| 11 |
-
"prefix": ""
|
| 12 |
-
},
|
| 13 |
-
"iconLibrary": "lucide",
|
| 14 |
-
"aliases": {
|
| 15 |
-
"components": "@/components",
|
| 16 |
-
"utils": "@/lib/utils",
|
| 17 |
-
"ui": "@/components/ui",
|
| 18 |
-
"lib": "@/lib",
|
| 19 |
-
"hooks": "@/hooks"
|
| 20 |
-
}
|
| 21 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/index.html
DELETED
|
@@ -1,31 +0,0 @@
|
|
| 1 |
-
<!DOCTYPE html>
|
| 2 |
-
<!--
|
| 3 |
-
This file is the entry for ALL routes, including /preview/* canvas iframes.
|
| 4 |
-
Fonts are loaded here as non-blocking <link> tags (not CSS @import, which is render-blocking).
|
| 5 |
-
-->
|
| 6 |
-
<html lang="en" style="height: 100%">
|
| 7 |
-
<head>
|
| 8 |
-
<meta charset="UTF-8" />
|
| 9 |
-
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1" />
|
| 10 |
-
|
| 11 |
-
<meta property="og:title" content="Mockup Canvas" />
|
| 12 |
-
<meta property="og:description" content="UI prototyping sandbox with infinite canvas" />
|
| 13 |
-
<meta property="og:type" content="website" />
|
| 14 |
-
<meta name="twitter:card" content="summary_large_image" />
|
| 15 |
-
<meta name="twitter:title" content="Mockup Canvas" />
|
| 16 |
-
<meta name="twitter:description" content="UI prototyping sandbox with infinite canvas" />
|
| 17 |
-
|
| 18 |
-
<title>Mockup Canvas</title>
|
| 19 |
-
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🎨</text></svg>">
|
| 20 |
-
<!-- Non-blocking font bundle: renders with fallback fonts immediately, swaps in when loaded -->
|
| 21 |
-
<link rel="preconnect" href="https://fonts.googleapis.com">
|
| 22 |
-
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
| 23 |
-
<link rel="stylesheet" media="print" onload="this.media='all'"
|
| 24 |
-
href="https://fonts.googleapis.com/css2?family=Architects+Daughter&family=DM+Sans:ital,opsz,wght@0,9..40,100..1000;1,9..40,100..1000&family=Fira+Code:wght@300..700&family=Geist+Mono:wght@100..900&family=Geist:wght@100..900&family=IBM+Plex+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&family=IBM+Plex+Sans:ital,wght@0,100..700;1,100..700&family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&family=Libre+Baskerville:ital,wght@0,400;0,700;1,400&family=Lora:ital,wght@0,400..700;1,400..700&family=Merriweather:ital,opsz,wght@0,18..144,300..900;1,18..144,300..900&family=Montserrat:ital,wght@0,100..900;1,100..900&family=Open+Sans:ital,wght@0,300..800;1,300..800&family=Outfit:wght@100..900&family=Oxanium:wght@200..800&family=Playfair+Display:ital,wght@0,400..900;1,400..900&family=Plus+Jakarta+Sans:ital,wght@0,200..800;1,200..800&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&family=Roboto+Mono:ital,wght@0,100..700;1,100..700&family=Roboto:ital,wght@0,100..900;1,100..900&family=Source+Code+Pro:ital,wght@0,200..900;1,200..900&family=Source+Serif+4:ital,opsz,wght@0,8..60,200..900;1,8..60,200..900&family=Space+Grotesk:wght@300..700&family=Space+Mono:ital,wght@0,400;0,700;1,400;1,700&display=swap">
|
| 25 |
-
<noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Architects+Daughter&family=DM+Sans:ital,opsz,wght@0,9..40,100..1000;1,9..40,100..1000&family=Fira+Code:wght@300..700&family=Geist+Mono:wght@100..900&family=Geist:wght@100..900&family=IBM+Plex+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&family=IBM+Plex+Sans:ital,wght@0,100..700;1,100..700&family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&family=Libre+Baskerville:ital,wght@0,400;0,700;1,400&family=Lora:ital,wght@0,400..700;1,400..700&family=Merriweather:ital,opsz,wght@0,18..144,300..900;1,18..144,300..900&family=Montserrat:ital,wght@0,100..900;1,100..900&family=Open+Sans:ital,wght@0,300..800;1,300..800&family=Outfit:wght@100..900&family=Oxanium:wght@200..800&family=Playfair+Display:ital,wght@0,400..900;1,400..900&family=Plus+Jakarta+Sans:ital,wght@0,200..800;1,200..800&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&family=Roboto+Mono:ital,wght@0,100..700;1,100..700&family=Roboto:ital,wght@0,100..900;1,100..900&family=Source+Code+Pro:ital,wght@0,200..900;1,200..900&family=Source+Serif+4:ital,opsz,wght@0,8..60,200..900;1,8..60,200..900&family=Space+Grotesk:wght@300..700&family=Space+Mono:ital,wght@0,400;0,700;1,400;1,700&display=swap"></noscript>
|
| 26 |
-
</head>
|
| 27 |
-
<body style="height: 100%; margin: 0">
|
| 28 |
-
<div id="root" style="height: 100%"></div>
|
| 29 |
-
<script type="module" src="/src/main.tsx"></script>
|
| 30 |
-
</body>
|
| 31 |
-
</html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/mockupPreviewPlugin.ts
DELETED
|
@@ -1,180 +0,0 @@
|
|
| 1 |
-
import { mkdirSync, writeFileSync } from "fs";
|
| 2 |
-
import path from "path";
|
| 3 |
-
import glob from "fast-glob";
|
| 4 |
-
import chokidar from "chokidar";
|
| 5 |
-
import type { FSWatcher } from "chokidar";
|
| 6 |
-
import type { Plugin } from "vite";
|
| 7 |
-
|
| 8 |
-
const MOCKUPS_DIR = "src/components/mockups";
|
| 9 |
-
const GENERATED_MODULE = "src/.generated/mockup-components.ts";
|
| 10 |
-
|
| 11 |
-
interface DiscoveredComponent {
|
| 12 |
-
globKey: string;
|
| 13 |
-
importPath: string;
|
| 14 |
-
}
|
| 15 |
-
|
| 16 |
-
export function mockupPreviewPlugin(): Plugin {
|
| 17 |
-
let root = "";
|
| 18 |
-
let currentSource = "";
|
| 19 |
-
let watcher: FSWatcher | null = null;
|
| 20 |
-
|
| 21 |
-
function getMockupsAbsDir(): string {
|
| 22 |
-
return path.join(root, MOCKUPS_DIR);
|
| 23 |
-
}
|
| 24 |
-
|
| 25 |
-
function getGeneratedModuleAbsPath(): string {
|
| 26 |
-
return path.join(root, GENERATED_MODULE);
|
| 27 |
-
}
|
| 28 |
-
|
| 29 |
-
function isMockupFile(absolutePath: string): boolean {
|
| 30 |
-
const rel = path.relative(getMockupsAbsDir(), absolutePath);
|
| 31 |
-
return (
|
| 32 |
-
!rel.startsWith("..") && !path.isAbsolute(rel) && rel.endsWith(".tsx")
|
| 33 |
-
);
|
| 34 |
-
}
|
| 35 |
-
|
| 36 |
-
function isPreviewTarget(relativeToMockups: string): boolean {
|
| 37 |
-
return relativeToMockups
|
| 38 |
-
.split(path.sep)
|
| 39 |
-
.every((segment) => !segment.startsWith("_"));
|
| 40 |
-
}
|
| 41 |
-
|
| 42 |
-
async function discoverComponents(): Promise<Array<DiscoveredComponent>> {
|
| 43 |
-
const files = await glob(`${MOCKUPS_DIR}/**/*.tsx`, {
|
| 44 |
-
cwd: root,
|
| 45 |
-
ignore: ["**/_*/**", "**/_*.tsx"],
|
| 46 |
-
});
|
| 47 |
-
|
| 48 |
-
return files.map((f) => ({
|
| 49 |
-
globKey: "./" + f.slice("src/".length),
|
| 50 |
-
importPath: path.posix.relative("src/.generated", f),
|
| 51 |
-
}));
|
| 52 |
-
}
|
| 53 |
-
|
| 54 |
-
function generateSource(components: Array<DiscoveredComponent>): string {
|
| 55 |
-
const entries = components
|
| 56 |
-
.map(
|
| 57 |
-
(c) =>
|
| 58 |
-
` ${JSON.stringify(c.globKey)}: () => import(${JSON.stringify(c.importPath)})`,
|
| 59 |
-
)
|
| 60 |
-
.join(",\n");
|
| 61 |
-
|
| 62 |
-
return [
|
| 63 |
-
"// This file is auto-generated by mockupPreviewPlugin.ts.",
|
| 64 |
-
"type ModuleMap = Record<string, () => Promise<Record<string, unknown>>>;",
|
| 65 |
-
"export const modules: ModuleMap = {",
|
| 66 |
-
entries,
|
| 67 |
-
"};",
|
| 68 |
-
"",
|
| 69 |
-
].join("\n");
|
| 70 |
-
}
|
| 71 |
-
|
| 72 |
-
function shouldAutoRescan(pathname: string): boolean {
|
| 73 |
-
return (
|
| 74 |
-
pathname.includes("/components/mockups/") ||
|
| 75 |
-
pathname.includes("/.generated/mockup-components")
|
| 76 |
-
);
|
| 77 |
-
}
|
| 78 |
-
|
| 79 |
-
let refreshInFlight = false;
|
| 80 |
-
let refreshQueued = false;
|
| 81 |
-
|
| 82 |
-
async function refresh(): Promise<boolean> {
|
| 83 |
-
if (refreshInFlight) {
|
| 84 |
-
refreshQueued = true;
|
| 85 |
-
return false;
|
| 86 |
-
}
|
| 87 |
-
|
| 88 |
-
refreshInFlight = true;
|
| 89 |
-
let changed = false;
|
| 90 |
-
try {
|
| 91 |
-
const components = await discoverComponents();
|
| 92 |
-
const newSource = generateSource(components);
|
| 93 |
-
if (newSource !== currentSource) {
|
| 94 |
-
currentSource = newSource;
|
| 95 |
-
const generatedModuleAbsPath = getGeneratedModuleAbsPath();
|
| 96 |
-
mkdirSync(path.dirname(generatedModuleAbsPath), { recursive: true });
|
| 97 |
-
writeFileSync(generatedModuleAbsPath, currentSource);
|
| 98 |
-
changed = true;
|
| 99 |
-
}
|
| 100 |
-
} finally {
|
| 101 |
-
refreshInFlight = false;
|
| 102 |
-
}
|
| 103 |
-
|
| 104 |
-
if (refreshQueued) {
|
| 105 |
-
refreshQueued = false;
|
| 106 |
-
const followUp = await refresh();
|
| 107 |
-
return changed || followUp;
|
| 108 |
-
}
|
| 109 |
-
|
| 110 |
-
return changed;
|
| 111 |
-
}
|
| 112 |
-
|
| 113 |
-
async function onFileAddedOrRemoved(): Promise<void> {
|
| 114 |
-
await refresh();
|
| 115 |
-
}
|
| 116 |
-
|
| 117 |
-
return {
|
| 118 |
-
name: "mockup-preview",
|
| 119 |
-
enforce: "pre",
|
| 120 |
-
|
| 121 |
-
configResolved(config) {
|
| 122 |
-
root = config.root;
|
| 123 |
-
},
|
| 124 |
-
|
| 125 |
-
async buildStart() {
|
| 126 |
-
await refresh();
|
| 127 |
-
},
|
| 128 |
-
|
| 129 |
-
async configureServer(viteServer) {
|
| 130 |
-
await refresh();
|
| 131 |
-
|
| 132 |
-
const mockupsAbsDir = getMockupsAbsDir();
|
| 133 |
-
mkdirSync(mockupsAbsDir, { recursive: true });
|
| 134 |
-
|
| 135 |
-
watcher = chokidar.watch(mockupsAbsDir, {
|
| 136 |
-
ignoreInitial: true,
|
| 137 |
-
awaitWriteFinish: {
|
| 138 |
-
stabilityThreshold: 100,
|
| 139 |
-
pollInterval: 50,
|
| 140 |
-
},
|
| 141 |
-
});
|
| 142 |
-
|
| 143 |
-
watcher.on("add", (file) => {
|
| 144 |
-
if (
|
| 145 |
-
isMockupFile(file) &&
|
| 146 |
-
isPreviewTarget(path.relative(mockupsAbsDir, file))
|
| 147 |
-
) {
|
| 148 |
-
void onFileAddedOrRemoved();
|
| 149 |
-
}
|
| 150 |
-
});
|
| 151 |
-
|
| 152 |
-
watcher.on("unlink", (file) => {
|
| 153 |
-
if (isMockupFile(file)) {
|
| 154 |
-
void onFileAddedOrRemoved();
|
| 155 |
-
}
|
| 156 |
-
});
|
| 157 |
-
|
| 158 |
-
viteServer.middlewares.use((req, res, next) => {
|
| 159 |
-
const requestUrl = new URL(req.url ?? "/", "http://127.0.0.1");
|
| 160 |
-
const pathname = requestUrl.pathname;
|
| 161 |
-
const originalEnd = res.end.bind(res);
|
| 162 |
-
|
| 163 |
-
res.end = ((...args: Parameters<typeof originalEnd>) => {
|
| 164 |
-
if (res.statusCode === 404 && shouldAutoRescan(pathname)) {
|
| 165 |
-
void refresh();
|
| 166 |
-
}
|
| 167 |
-
return originalEnd(...args);
|
| 168 |
-
}) as typeof res.end;
|
| 169 |
-
|
| 170 |
-
next();
|
| 171 |
-
});
|
| 172 |
-
},
|
| 173 |
-
|
| 174 |
-
async closeWatcher() {
|
| 175 |
-
if (watcher) {
|
| 176 |
-
await watcher.close();
|
| 177 |
-
}
|
| 178 |
-
},
|
| 179 |
-
};
|
| 180 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/package.json
DELETED
|
@@ -1,74 +0,0 @@
|
|
| 1 |
-
{
|
| 2 |
-
"name": "@workspace/mockup-sandbox",
|
| 3 |
-
"version": "2.0.0",
|
| 4 |
-
"type": "module",
|
| 5 |
-
"private": true,
|
| 6 |
-
"scripts": {
|
| 7 |
-
"dev": "vite dev",
|
| 8 |
-
"build": "vite build",
|
| 9 |
-
"preview": "vite preview",
|
| 10 |
-
"typecheck": "tsc -p tsconfig.json --noEmit"
|
| 11 |
-
},
|
| 12 |
-
"devDependencies": {
|
| 13 |
-
"@hookform/resolvers": "^3.10.0",
|
| 14 |
-
"@radix-ui/react-accordion": "^1.2.12",
|
| 15 |
-
"@radix-ui/react-alert-dialog": "^1.1.15",
|
| 16 |
-
"@radix-ui/react-aspect-ratio": "^1.1.8",
|
| 17 |
-
"@radix-ui/react-avatar": "^1.1.11",
|
| 18 |
-
"@radix-ui/react-checkbox": "^1.3.3",
|
| 19 |
-
"@radix-ui/react-collapsible": "^1.1.12",
|
| 20 |
-
"@radix-ui/react-context-menu": "^2.2.16",
|
| 21 |
-
"@radix-ui/react-dialog": "^1.1.15",
|
| 22 |
-
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
| 23 |
-
"@radix-ui/react-hover-card": "^1.1.15",
|
| 24 |
-
"@radix-ui/react-label": "^2.1.8",
|
| 25 |
-
"@radix-ui/react-menubar": "^1.1.16",
|
| 26 |
-
"@radix-ui/react-navigation-menu": "^1.2.14",
|
| 27 |
-
"@radix-ui/react-popover": "^1.1.15",
|
| 28 |
-
"@radix-ui/react-progress": "^1.1.8",
|
| 29 |
-
"@radix-ui/react-radio-group": "^1.3.8",
|
| 30 |
-
"@radix-ui/react-scroll-area": "^1.2.10",
|
| 31 |
-
"@radix-ui/react-select": "^2.2.6",
|
| 32 |
-
"@radix-ui/react-separator": "^1.1.8",
|
| 33 |
-
"@radix-ui/react-slider": "^1.3.6",
|
| 34 |
-
"@radix-ui/react-slot": "^1.2.4",
|
| 35 |
-
"@radix-ui/react-switch": "^1.2.6",
|
| 36 |
-
"@radix-ui/react-tabs": "^1.1.13",
|
| 37 |
-
"@radix-ui/react-toast": "^1.2.7",
|
| 38 |
-
"@radix-ui/react-toggle": "^1.1.10",
|
| 39 |
-
"@radix-ui/react-toggle-group": "^1.1.11",
|
| 40 |
-
"@radix-ui/react-tooltip": "^1.2.8",
|
| 41 |
-
"@replit/vite-plugin-cartographer": "catalog:",
|
| 42 |
-
"@replit/vite-plugin-runtime-error-modal": "catalog:",
|
| 43 |
-
"@tailwindcss/vite": "catalog:",
|
| 44 |
-
"@types/node": "catalog:",
|
| 45 |
-
"@types/react": "catalog:",
|
| 46 |
-
"@types/react-dom": "catalog:",
|
| 47 |
-
"@vitejs/plugin-react": "catalog:",
|
| 48 |
-
"chokidar": "^4.0.3",
|
| 49 |
-
"class-variance-authority": "catalog:",
|
| 50 |
-
"clsx": "catalog:",
|
| 51 |
-
"cmdk": "^1.1.1",
|
| 52 |
-
"date-fns": "^3.6.0",
|
| 53 |
-
"embla-carousel-react": "^8.6.0",
|
| 54 |
-
"fast-glob": "^3.3.3",
|
| 55 |
-
"framer-motion": "catalog:",
|
| 56 |
-
"input-otp": "^1.4.2",
|
| 57 |
-
"lucide-react": "catalog:",
|
| 58 |
-
"next-themes": "^0.4.6",
|
| 59 |
-
"react": "catalog:",
|
| 60 |
-
"react-day-picker": "^9.11.1",
|
| 61 |
-
"react-dom": "catalog:",
|
| 62 |
-
"react-hook-form": "^7.66.0",
|
| 63 |
-
"react-resizable-panels": "^2.1.9",
|
| 64 |
-
"recharts": "^2.15.4",
|
| 65 |
-
"sonner": "^2.0.7",
|
| 66 |
-
"tailwind-merge": "catalog:",
|
| 67 |
-
"tailwindcss": "catalog:",
|
| 68 |
-
"tailwindcss-animate": "^1.0.7",
|
| 69 |
-
"tw-animate-css": "^1.4.0",
|
| 70 |
-
"vaul": "^1.1.2",
|
| 71 |
-
"vite": "catalog:",
|
| 72 |
-
"zod": "catalog:"
|
| 73 |
-
}
|
| 74 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/.generated/mockup-components.ts
DELETED
|
@@ -1,5 +0,0 @@
|
|
| 1 |
-
// This file is auto-generated by mockupPreviewPlugin.ts.
|
| 2 |
-
type ModuleMap = Record<string, () => Promise<Record<string, unknown>>>;
|
| 3 |
-
export const modules: ModuleMap = {
|
| 4 |
-
|
| 5 |
-
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/App.tsx
DELETED
|
@@ -1,146 +0,0 @@
|
|
| 1 |
-
import { useEffect, useState, type ComponentType } from "react";
|
| 2 |
-
|
| 3 |
-
import { modules as discoveredModules } from "./.generated/mockup-components";
|
| 4 |
-
|
| 5 |
-
type ModuleMap = Record<string, () => Promise<Record<string, unknown>>>;
|
| 6 |
-
|
| 7 |
-
function _resolveComponent(
|
| 8 |
-
mod: Record<string, unknown>,
|
| 9 |
-
name: string,
|
| 10 |
-
): ComponentType | undefined {
|
| 11 |
-
const fns = Object.values(mod).filter(
|
| 12 |
-
(v) => typeof v === "function",
|
| 13 |
-
) as ComponentType[];
|
| 14 |
-
return (
|
| 15 |
-
(mod.default as ComponentType) ||
|
| 16 |
-
(mod.Preview as ComponentType) ||
|
| 17 |
-
(mod[name] as ComponentType) ||
|
| 18 |
-
fns[fns.length - 1]
|
| 19 |
-
);
|
| 20 |
-
}
|
| 21 |
-
|
| 22 |
-
function PreviewRenderer({
|
| 23 |
-
componentPath,
|
| 24 |
-
modules,
|
| 25 |
-
}: {
|
| 26 |
-
componentPath: string;
|
| 27 |
-
modules: ModuleMap;
|
| 28 |
-
}) {
|
| 29 |
-
const [Component, setComponent] = useState<ComponentType | null>(null);
|
| 30 |
-
const [error, setError] = useState<string | null>(null);
|
| 31 |
-
|
| 32 |
-
useEffect(() => {
|
| 33 |
-
let cancelled = false;
|
| 34 |
-
|
| 35 |
-
setComponent(null);
|
| 36 |
-
setError(null);
|
| 37 |
-
|
| 38 |
-
async function loadComponent(): Promise<void> {
|
| 39 |
-
const key = `./components/mockups/${componentPath}.tsx`;
|
| 40 |
-
const loader = modules[key];
|
| 41 |
-
if (!loader) {
|
| 42 |
-
setError(`No component found at ${componentPath}.tsx`);
|
| 43 |
-
return;
|
| 44 |
-
}
|
| 45 |
-
|
| 46 |
-
try {
|
| 47 |
-
const mod = await loader();
|
| 48 |
-
if (cancelled) {
|
| 49 |
-
return;
|
| 50 |
-
}
|
| 51 |
-
const name = componentPath.split("/").pop()!;
|
| 52 |
-
const comp = _resolveComponent(mod, name);
|
| 53 |
-
if (!comp) {
|
| 54 |
-
setError(
|
| 55 |
-
`No exported React component found in ${componentPath}.tsx\n\nMake sure the file has at least one exported function component.`,
|
| 56 |
-
);
|
| 57 |
-
return;
|
| 58 |
-
}
|
| 59 |
-
setComponent(() => comp);
|
| 60 |
-
} catch (e) {
|
| 61 |
-
if (cancelled) {
|
| 62 |
-
return;
|
| 63 |
-
}
|
| 64 |
-
|
| 65 |
-
const message = e instanceof Error ? e.message : String(e);
|
| 66 |
-
setError(`Failed to load preview.\n${message}`);
|
| 67 |
-
}
|
| 68 |
-
}
|
| 69 |
-
|
| 70 |
-
void loadComponent();
|
| 71 |
-
|
| 72 |
-
return () => {
|
| 73 |
-
cancelled = true;
|
| 74 |
-
};
|
| 75 |
-
}, [componentPath, modules]);
|
| 76 |
-
|
| 77 |
-
if (error) {
|
| 78 |
-
return (
|
| 79 |
-
<pre style={{ color: "red", padding: "2rem", fontFamily: "system-ui" }}>
|
| 80 |
-
{error}
|
| 81 |
-
</pre>
|
| 82 |
-
);
|
| 83 |
-
}
|
| 84 |
-
|
| 85 |
-
if (!Component) return null;
|
| 86 |
-
|
| 87 |
-
return <Component />;
|
| 88 |
-
}
|
| 89 |
-
|
| 90 |
-
function getBasePath(): string {
|
| 91 |
-
return import.meta.env.BASE_URL.replace(/\/$/, "");
|
| 92 |
-
}
|
| 93 |
-
|
| 94 |
-
function getPreviewExamplePath(): string {
|
| 95 |
-
const basePath = getBasePath();
|
| 96 |
-
return `${basePath}/preview/ComponentName`;
|
| 97 |
-
}
|
| 98 |
-
|
| 99 |
-
function Gallery() {
|
| 100 |
-
return (
|
| 101 |
-
<div className="min-h-screen bg-gray-50 flex items-center justify-center p-8">
|
| 102 |
-
<div className="text-center max-w-md">
|
| 103 |
-
<h1 className="text-2xl font-semibold text-gray-900 mb-3">
|
| 104 |
-
Component Preview Server
|
| 105 |
-
</h1>
|
| 106 |
-
<p className="text-gray-500 mb-4">
|
| 107 |
-
This server renders individual components for the workspace canvas.
|
| 108 |
-
</p>
|
| 109 |
-
<p className="text-sm text-gray-400">
|
| 110 |
-
Access component previews at{" "}
|
| 111 |
-
<code className="bg-gray-100 px-1.5 py-0.5 rounded text-gray-600">
|
| 112 |
-
{getPreviewExamplePath()}
|
| 113 |
-
</code>
|
| 114 |
-
</p>
|
| 115 |
-
</div>
|
| 116 |
-
</div>
|
| 117 |
-
);
|
| 118 |
-
}
|
| 119 |
-
|
| 120 |
-
function getPreviewPath(): string | null {
|
| 121 |
-
const basePath = getBasePath();
|
| 122 |
-
const { pathname } = window.location;
|
| 123 |
-
const local =
|
| 124 |
-
basePath && pathname.startsWith(basePath)
|
| 125 |
-
? pathname.slice(basePath.length) || "/"
|
| 126 |
-
: pathname;
|
| 127 |
-
const match = local.match(/^\/preview\/(.+)$/);
|
| 128 |
-
return match ? match[1] : null;
|
| 129 |
-
}
|
| 130 |
-
|
| 131 |
-
function App() {
|
| 132 |
-
const previewPath = getPreviewPath();
|
| 133 |
-
|
| 134 |
-
if (previewPath) {
|
| 135 |
-
return (
|
| 136 |
-
<PreviewRenderer
|
| 137 |
-
componentPath={previewPath}
|
| 138 |
-
modules={discoveredModules}
|
| 139 |
-
/>
|
| 140 |
-
);
|
| 141 |
-
}
|
| 142 |
-
|
| 143 |
-
return <Gallery />;
|
| 144 |
-
}
|
| 145 |
-
|
| 146 |
-
export default App;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/accordion.tsx
DELETED
|
@@ -1,55 +0,0 @@
|
|
| 1 |
-
import * as React from "react"
|
| 2 |
-
import * as AccordionPrimitive from "@radix-ui/react-accordion"
|
| 3 |
-
import { ChevronDown } from "lucide-react"
|
| 4 |
-
|
| 5 |
-
import { cn } from "@/lib/utils"
|
| 6 |
-
|
| 7 |
-
const Accordion = AccordionPrimitive.Root
|
| 8 |
-
|
| 9 |
-
const AccordionItem = React.forwardRef<
|
| 10 |
-
React.ElementRef<typeof AccordionPrimitive.Item>,
|
| 11 |
-
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
|
| 12 |
-
>(({ className, ...props }, ref) => (
|
| 13 |
-
<AccordionPrimitive.Item
|
| 14 |
-
ref={ref}
|
| 15 |
-
className={cn("border-b", className)}
|
| 16 |
-
{...props}
|
| 17 |
-
/>
|
| 18 |
-
))
|
| 19 |
-
AccordionItem.displayName = "AccordionItem"
|
| 20 |
-
|
| 21 |
-
const AccordionTrigger = React.forwardRef<
|
| 22 |
-
React.ElementRef<typeof AccordionPrimitive.Trigger>,
|
| 23 |
-
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger>
|
| 24 |
-
>(({ className, children, ...props }, ref) => (
|
| 25 |
-
<AccordionPrimitive.Header className="flex">
|
| 26 |
-
<AccordionPrimitive.Trigger
|
| 27 |
-
ref={ref}
|
| 28 |
-
className={cn(
|
| 29 |
-
"flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline text-left [&[data-state=open]>svg]:rotate-180",
|
| 30 |
-
className
|
| 31 |
-
)}
|
| 32 |
-
{...props}
|
| 33 |
-
>
|
| 34 |
-
{children}
|
| 35 |
-
<ChevronDown className="h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-200" />
|
| 36 |
-
</AccordionPrimitive.Trigger>
|
| 37 |
-
</AccordionPrimitive.Header>
|
| 38 |
-
))
|
| 39 |
-
AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName
|
| 40 |
-
|
| 41 |
-
const AccordionContent = React.forwardRef<
|
| 42 |
-
React.ElementRef<typeof AccordionPrimitive.Content>,
|
| 43 |
-
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content>
|
| 44 |
-
>(({ className, children, ...props }, ref) => (
|
| 45 |
-
<AccordionPrimitive.Content
|
| 46 |
-
ref={ref}
|
| 47 |
-
className="overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
|
| 48 |
-
{...props}
|
| 49 |
-
>
|
| 50 |
-
<div className={cn("pb-4 pt-0", className)}>{children}</div>
|
| 51 |
-
</AccordionPrimitive.Content>
|
| 52 |
-
))
|
| 53 |
-
AccordionContent.displayName = AccordionPrimitive.Content.displayName
|
| 54 |
-
|
| 55 |
-
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/alert-dialog.tsx
DELETED
|
@@ -1,139 +0,0 @@
|
|
| 1 |
-
import * as React from "react"
|
| 2 |
-
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog"
|
| 3 |
-
|
| 4 |
-
import { cn } from "@/lib/utils"
|
| 5 |
-
import { buttonVariants } from "@/components/ui/button"
|
| 6 |
-
|
| 7 |
-
const AlertDialog = AlertDialogPrimitive.Root
|
| 8 |
-
|
| 9 |
-
const AlertDialogTrigger = AlertDialogPrimitive.Trigger
|
| 10 |
-
|
| 11 |
-
const AlertDialogPortal = AlertDialogPrimitive.Portal
|
| 12 |
-
|
| 13 |
-
const AlertDialogOverlay = React.forwardRef<
|
| 14 |
-
React.ElementRef<typeof AlertDialogPrimitive.Overlay>,
|
| 15 |
-
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Overlay>
|
| 16 |
-
>(({ className, ...props }, ref) => (
|
| 17 |
-
<AlertDialogPrimitive.Overlay
|
| 18 |
-
className={cn(
|
| 19 |
-
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
| 20 |
-
className
|
| 21 |
-
)}
|
| 22 |
-
{...props}
|
| 23 |
-
ref={ref}
|
| 24 |
-
/>
|
| 25 |
-
))
|
| 26 |
-
AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName
|
| 27 |
-
|
| 28 |
-
const AlertDialogContent = React.forwardRef<
|
| 29 |
-
React.ElementRef<typeof AlertDialogPrimitive.Content>,
|
| 30 |
-
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Content>
|
| 31 |
-
>(({ className, ...props }, ref) => (
|
| 32 |
-
<AlertDialogPortal>
|
| 33 |
-
<AlertDialogOverlay />
|
| 34 |
-
<AlertDialogPrimitive.Content
|
| 35 |
-
ref={ref}
|
| 36 |
-
className={cn(
|
| 37 |
-
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 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-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
|
| 38 |
-
className
|
| 39 |
-
)}
|
| 40 |
-
{...props}
|
| 41 |
-
/>
|
| 42 |
-
</AlertDialogPortal>
|
| 43 |
-
))
|
| 44 |
-
AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName
|
| 45 |
-
|
| 46 |
-
const AlertDialogHeader = ({
|
| 47 |
-
className,
|
| 48 |
-
...props
|
| 49 |
-
}: React.HTMLAttributes<HTMLDivElement>) => (
|
| 50 |
-
<div
|
| 51 |
-
className={cn(
|
| 52 |
-
"flex flex-col space-y-2 text-center sm:text-left",
|
| 53 |
-
className
|
| 54 |
-
)}
|
| 55 |
-
{...props}
|
| 56 |
-
/>
|
| 57 |
-
)
|
| 58 |
-
AlertDialogHeader.displayName = "AlertDialogHeader"
|
| 59 |
-
|
| 60 |
-
const AlertDialogFooter = ({
|
| 61 |
-
className,
|
| 62 |
-
...props
|
| 63 |
-
}: React.HTMLAttributes<HTMLDivElement>) => (
|
| 64 |
-
<div
|
| 65 |
-
className={cn(
|
| 66 |
-
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
|
| 67 |
-
className
|
| 68 |
-
)}
|
| 69 |
-
{...props}
|
| 70 |
-
/>
|
| 71 |
-
)
|
| 72 |
-
AlertDialogFooter.displayName = "AlertDialogFooter"
|
| 73 |
-
|
| 74 |
-
const AlertDialogTitle = React.forwardRef<
|
| 75 |
-
React.ElementRef<typeof AlertDialogPrimitive.Title>,
|
| 76 |
-
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Title>
|
| 77 |
-
>(({ className, ...props }, ref) => (
|
| 78 |
-
<AlertDialogPrimitive.Title
|
| 79 |
-
ref={ref}
|
| 80 |
-
className={cn("text-lg font-semibold", className)}
|
| 81 |
-
{...props}
|
| 82 |
-
/>
|
| 83 |
-
))
|
| 84 |
-
AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName
|
| 85 |
-
|
| 86 |
-
const AlertDialogDescription = React.forwardRef<
|
| 87 |
-
React.ElementRef<typeof AlertDialogPrimitive.Description>,
|
| 88 |
-
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Description>
|
| 89 |
-
>(({ className, ...props }, ref) => (
|
| 90 |
-
<AlertDialogPrimitive.Description
|
| 91 |
-
ref={ref}
|
| 92 |
-
className={cn("text-sm text-muted-foreground", className)}
|
| 93 |
-
{...props}
|
| 94 |
-
/>
|
| 95 |
-
))
|
| 96 |
-
AlertDialogDescription.displayName =
|
| 97 |
-
AlertDialogPrimitive.Description.displayName
|
| 98 |
-
|
| 99 |
-
const AlertDialogAction = React.forwardRef<
|
| 100 |
-
React.ElementRef<typeof AlertDialogPrimitive.Action>,
|
| 101 |
-
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Action>
|
| 102 |
-
>(({ className, ...props }, ref) => (
|
| 103 |
-
<AlertDialogPrimitive.Action
|
| 104 |
-
ref={ref}
|
| 105 |
-
className={cn(buttonVariants(), className)}
|
| 106 |
-
{...props}
|
| 107 |
-
/>
|
| 108 |
-
))
|
| 109 |
-
AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName
|
| 110 |
-
|
| 111 |
-
const AlertDialogCancel = React.forwardRef<
|
| 112 |
-
React.ElementRef<typeof AlertDialogPrimitive.Cancel>,
|
| 113 |
-
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Cancel>
|
| 114 |
-
>(({ className, ...props }, ref) => (
|
| 115 |
-
<AlertDialogPrimitive.Cancel
|
| 116 |
-
ref={ref}
|
| 117 |
-
className={cn(
|
| 118 |
-
buttonVariants({ variant: "outline" }),
|
| 119 |
-
"mt-2 sm:mt-0",
|
| 120 |
-
className
|
| 121 |
-
)}
|
| 122 |
-
{...props}
|
| 123 |
-
/>
|
| 124 |
-
))
|
| 125 |
-
AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName
|
| 126 |
-
|
| 127 |
-
export {
|
| 128 |
-
AlertDialog,
|
| 129 |
-
AlertDialogPortal,
|
| 130 |
-
AlertDialogOverlay,
|
| 131 |
-
AlertDialogTrigger,
|
| 132 |
-
AlertDialogContent,
|
| 133 |
-
AlertDialogHeader,
|
| 134 |
-
AlertDialogFooter,
|
| 135 |
-
AlertDialogTitle,
|
| 136 |
-
AlertDialogDescription,
|
| 137 |
-
AlertDialogAction,
|
| 138 |
-
AlertDialogCancel,
|
| 139 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/alert.tsx
DELETED
|
@@ -1,59 +0,0 @@
|
|
| 1 |
-
import * as React from "react"
|
| 2 |
-
import { cva, type VariantProps } from "class-variance-authority"
|
| 3 |
-
|
| 4 |
-
import { cn } from "@/lib/utils"
|
| 5 |
-
|
| 6 |
-
const alertVariants = cva(
|
| 7 |
-
"relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7",
|
| 8 |
-
{
|
| 9 |
-
variants: {
|
| 10 |
-
variant: {
|
| 11 |
-
default: "bg-background text-foreground",
|
| 12 |
-
destructive:
|
| 13 |
-
"border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive",
|
| 14 |
-
},
|
| 15 |
-
},
|
| 16 |
-
defaultVariants: {
|
| 17 |
-
variant: "default",
|
| 18 |
-
},
|
| 19 |
-
}
|
| 20 |
-
)
|
| 21 |
-
|
| 22 |
-
const Alert = React.forwardRef<
|
| 23 |
-
HTMLDivElement,
|
| 24 |
-
React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>
|
| 25 |
-
>(({ className, variant, ...props }, ref) => (
|
| 26 |
-
<div
|
| 27 |
-
ref={ref}
|
| 28 |
-
role="alert"
|
| 29 |
-
className={cn(alertVariants({ variant }), className)}
|
| 30 |
-
{...props}
|
| 31 |
-
/>
|
| 32 |
-
))
|
| 33 |
-
Alert.displayName = "Alert"
|
| 34 |
-
|
| 35 |
-
const AlertTitle = React.forwardRef<
|
| 36 |
-
HTMLParagraphElement,
|
| 37 |
-
React.HTMLAttributes<HTMLHeadingElement>
|
| 38 |
-
>(({ className, ...props }, ref) => (
|
| 39 |
-
<h5
|
| 40 |
-
ref={ref}
|
| 41 |
-
className={cn("mb-1 font-medium leading-none tracking-tight", className)}
|
| 42 |
-
{...props}
|
| 43 |
-
/>
|
| 44 |
-
))
|
| 45 |
-
AlertTitle.displayName = "AlertTitle"
|
| 46 |
-
|
| 47 |
-
const AlertDescription = React.forwardRef<
|
| 48 |
-
HTMLParagraphElement,
|
| 49 |
-
React.HTMLAttributes<HTMLParagraphElement>
|
| 50 |
-
>(({ className, ...props }, ref) => (
|
| 51 |
-
<div
|
| 52 |
-
ref={ref}
|
| 53 |
-
className={cn("text-sm [&_p]:leading-relaxed", className)}
|
| 54 |
-
{...props}
|
| 55 |
-
/>
|
| 56 |
-
))
|
| 57 |
-
AlertDescription.displayName = "AlertDescription"
|
| 58 |
-
|
| 59 |
-
export { Alert, AlertTitle, AlertDescription }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/aspect-ratio.tsx
DELETED
|
@@ -1,5 +0,0 @@
|
|
| 1 |
-
import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio"
|
| 2 |
-
|
| 3 |
-
const AspectRatio = AspectRatioPrimitive.Root
|
| 4 |
-
|
| 5 |
-
export { AspectRatio }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/avatar.tsx
DELETED
|
@@ -1,50 +0,0 @@
|
|
| 1 |
-
"use client"
|
| 2 |
-
|
| 3 |
-
import * as React from "react"
|
| 4 |
-
import * as AvatarPrimitive from "@radix-ui/react-avatar"
|
| 5 |
-
|
| 6 |
-
import { cn } from "@/lib/utils"
|
| 7 |
-
|
| 8 |
-
const Avatar = React.forwardRef<
|
| 9 |
-
React.ElementRef<typeof AvatarPrimitive.Root>,
|
| 10 |
-
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
|
| 11 |
-
>(({ className, ...props }, ref) => (
|
| 12 |
-
<AvatarPrimitive.Root
|
| 13 |
-
ref={ref}
|
| 14 |
-
className={cn(
|
| 15 |
-
"relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
|
| 16 |
-
className
|
| 17 |
-
)}
|
| 18 |
-
{...props}
|
| 19 |
-
/>
|
| 20 |
-
))
|
| 21 |
-
Avatar.displayName = AvatarPrimitive.Root.displayName
|
| 22 |
-
|
| 23 |
-
const AvatarImage = React.forwardRef<
|
| 24 |
-
React.ElementRef<typeof AvatarPrimitive.Image>,
|
| 25 |
-
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
|
| 26 |
-
>(({ className, ...props }, ref) => (
|
| 27 |
-
<AvatarPrimitive.Image
|
| 28 |
-
ref={ref}
|
| 29 |
-
className={cn("aspect-square h-full w-full", className)}
|
| 30 |
-
{...props}
|
| 31 |
-
/>
|
| 32 |
-
))
|
| 33 |
-
AvatarImage.displayName = AvatarPrimitive.Image.displayName
|
| 34 |
-
|
| 35 |
-
const AvatarFallback = React.forwardRef<
|
| 36 |
-
React.ElementRef<typeof AvatarPrimitive.Fallback>,
|
| 37 |
-
React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
|
| 38 |
-
>(({ className, ...props }, ref) => (
|
| 39 |
-
<AvatarPrimitive.Fallback
|
| 40 |
-
ref={ref}
|
| 41 |
-
className={cn(
|
| 42 |
-
"flex h-full w-full items-center justify-center rounded-full bg-muted",
|
| 43 |
-
className
|
| 44 |
-
)}
|
| 45 |
-
{...props}
|
| 46 |
-
/>
|
| 47 |
-
))
|
| 48 |
-
AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName
|
| 49 |
-
|
| 50 |
-
export { Avatar, AvatarImage, AvatarFallback }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/badge.tsx
DELETED
|
@@ -1,37 +0,0 @@
|
|
| 1 |
-
import * as React from "react"
|
| 2 |
-
import { cva, type VariantProps } from "class-variance-authority"
|
| 3 |
-
|
| 4 |
-
import { cn } from "@/lib/utils"
|
| 5 |
-
|
| 6 |
-
const badgeVariants = cva(
|
| 7 |
-
"whitespace-nowrap inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2" +
|
| 8 |
-
" hover-elevate ",
|
| 9 |
-
{
|
| 10 |
-
variants: {
|
| 11 |
-
variant: {
|
| 12 |
-
default:
|
| 13 |
-
"border-transparent bg-primary text-primary-foreground shadow-xs",
|
| 14 |
-
secondary:
|
| 15 |
-
"border-transparent bg-secondary text-secondary-foreground",
|
| 16 |
-
destructive:
|
| 17 |
-
"border-transparent bg-destructive text-destructive-foreground shadow-xs",
|
| 18 |
-
outline: "text-foreground border [border-color:var(--badge-outline)]",
|
| 19 |
-
},
|
| 20 |
-
},
|
| 21 |
-
defaultVariants: {
|
| 22 |
-
variant: "default",
|
| 23 |
-
},
|
| 24 |
-
}
|
| 25 |
-
)
|
| 26 |
-
|
| 27 |
-
export interface BadgeProps
|
| 28 |
-
extends React.HTMLAttributes<HTMLDivElement>,
|
| 29 |
-
VariantProps<typeof badgeVariants> {}
|
| 30 |
-
|
| 31 |
-
function Badge({ className, variant, ...props }: BadgeProps) {
|
| 32 |
-
return (
|
| 33 |
-
<div className={cn(badgeVariants({ variant }), className)} {...props} />
|
| 34 |
-
)
|
| 35 |
-
}
|
| 36 |
-
|
| 37 |
-
export { Badge, badgeVariants }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/breadcrumb.tsx
DELETED
|
@@ -1,115 +0,0 @@
|
|
| 1 |
-
import * as React from "react"
|
| 2 |
-
import { Slot } from "@radix-ui/react-slot"
|
| 3 |
-
import { ChevronRight, MoreHorizontal } from "lucide-react"
|
| 4 |
-
|
| 5 |
-
import { cn } from "@/lib/utils"
|
| 6 |
-
|
| 7 |
-
const Breadcrumb = React.forwardRef<
|
| 8 |
-
HTMLElement,
|
| 9 |
-
React.ComponentPropsWithoutRef<"nav"> & {
|
| 10 |
-
separator?: React.ReactNode
|
| 11 |
-
}
|
| 12 |
-
>(({ ...props }, ref) => <nav ref={ref} aria-label="breadcrumb" {...props} />)
|
| 13 |
-
Breadcrumb.displayName = "Breadcrumb"
|
| 14 |
-
|
| 15 |
-
const BreadcrumbList = React.forwardRef<
|
| 16 |
-
HTMLOListElement,
|
| 17 |
-
React.ComponentPropsWithoutRef<"ol">
|
| 18 |
-
>(({ className, ...props }, ref) => (
|
| 19 |
-
<ol
|
| 20 |
-
ref={ref}
|
| 21 |
-
className={cn(
|
| 22 |
-
"flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5",
|
| 23 |
-
className
|
| 24 |
-
)}
|
| 25 |
-
{...props}
|
| 26 |
-
/>
|
| 27 |
-
))
|
| 28 |
-
BreadcrumbList.displayName = "BreadcrumbList"
|
| 29 |
-
|
| 30 |
-
const BreadcrumbItem = React.forwardRef<
|
| 31 |
-
HTMLLIElement,
|
| 32 |
-
React.ComponentPropsWithoutRef<"li">
|
| 33 |
-
>(({ className, ...props }, ref) => (
|
| 34 |
-
<li
|
| 35 |
-
ref={ref}
|
| 36 |
-
className={cn("inline-flex items-center gap-1.5", className)}
|
| 37 |
-
{...props}
|
| 38 |
-
/>
|
| 39 |
-
))
|
| 40 |
-
BreadcrumbItem.displayName = "BreadcrumbItem"
|
| 41 |
-
|
| 42 |
-
const BreadcrumbLink = React.forwardRef<
|
| 43 |
-
HTMLAnchorElement,
|
| 44 |
-
React.ComponentPropsWithoutRef<"a"> & {
|
| 45 |
-
asChild?: boolean
|
| 46 |
-
}
|
| 47 |
-
>(({ asChild, className, ...props }, ref) => {
|
| 48 |
-
const Comp = asChild ? Slot : "a"
|
| 49 |
-
|
| 50 |
-
return (
|
| 51 |
-
<Comp
|
| 52 |
-
ref={ref}
|
| 53 |
-
className={cn("transition-colors hover:text-foreground", className)}
|
| 54 |
-
{...props}
|
| 55 |
-
/>
|
| 56 |
-
)
|
| 57 |
-
})
|
| 58 |
-
BreadcrumbLink.displayName = "BreadcrumbLink"
|
| 59 |
-
|
| 60 |
-
const BreadcrumbPage = React.forwardRef<
|
| 61 |
-
HTMLSpanElement,
|
| 62 |
-
React.ComponentPropsWithoutRef<"span">
|
| 63 |
-
>(({ className, ...props }, ref) => (
|
| 64 |
-
<span
|
| 65 |
-
ref={ref}
|
| 66 |
-
role="link"
|
| 67 |
-
aria-disabled="true"
|
| 68 |
-
aria-current="page"
|
| 69 |
-
className={cn("font-normal text-foreground", className)}
|
| 70 |
-
{...props}
|
| 71 |
-
/>
|
| 72 |
-
))
|
| 73 |
-
BreadcrumbPage.displayName = "BreadcrumbPage"
|
| 74 |
-
|
| 75 |
-
const BreadcrumbSeparator = ({
|
| 76 |
-
children,
|
| 77 |
-
className,
|
| 78 |
-
...props
|
| 79 |
-
}: React.ComponentProps<"li">) => (
|
| 80 |
-
<li
|
| 81 |
-
role="presentation"
|
| 82 |
-
aria-hidden="true"
|
| 83 |
-
className={cn("[&>svg]:w-3.5 [&>svg]:h-3.5", className)}
|
| 84 |
-
{...props}
|
| 85 |
-
>
|
| 86 |
-
{children ?? <ChevronRight />}
|
| 87 |
-
</li>
|
| 88 |
-
)
|
| 89 |
-
BreadcrumbSeparator.displayName = "BreadcrumbSeparator"
|
| 90 |
-
|
| 91 |
-
const BreadcrumbEllipsis = ({
|
| 92 |
-
className,
|
| 93 |
-
...props
|
| 94 |
-
}: React.ComponentProps<"span">) => (
|
| 95 |
-
<span
|
| 96 |
-
role="presentation"
|
| 97 |
-
aria-hidden="true"
|
| 98 |
-
className={cn("flex h-9 w-9 items-center justify-center", className)}
|
| 99 |
-
{...props}
|
| 100 |
-
>
|
| 101 |
-
<MoreHorizontal className="h-4 w-4" />
|
| 102 |
-
<span className="sr-only">More</span>
|
| 103 |
-
</span>
|
| 104 |
-
)
|
| 105 |
-
BreadcrumbEllipsis.displayName = "BreadcrumbElipssis"
|
| 106 |
-
|
| 107 |
-
export {
|
| 108 |
-
Breadcrumb,
|
| 109 |
-
BreadcrumbList,
|
| 110 |
-
BreadcrumbItem,
|
| 111 |
-
BreadcrumbLink,
|
| 112 |
-
BreadcrumbPage,
|
| 113 |
-
BreadcrumbSeparator,
|
| 114 |
-
BreadcrumbEllipsis,
|
| 115 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/button-group.tsx
DELETED
|
@@ -1,83 +0,0 @@
|
|
| 1 |
-
import { Slot } from "@radix-ui/react-slot"
|
| 2 |
-
import { cva, type VariantProps } from "class-variance-authority"
|
| 3 |
-
|
| 4 |
-
import { cn } from "@/lib/utils"
|
| 5 |
-
import { Separator } from "@/components/ui/separator"
|
| 6 |
-
|
| 7 |
-
const buttonGroupVariants = cva(
|
| 8 |
-
"flex w-fit items-stretch has-[>[data-slot=button-group]]:gap-2 [&>*]:focus-visible:relative [&>*]:focus-visible:z-10 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1",
|
| 9 |
-
{
|
| 10 |
-
variants: {
|
| 11 |
-
orientation: {
|
| 12 |
-
horizontal:
|
| 13 |
-
"[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none",
|
| 14 |
-
vertical:
|
| 15 |
-
"flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none",
|
| 16 |
-
},
|
| 17 |
-
},
|
| 18 |
-
defaultVariants: {
|
| 19 |
-
orientation: "horizontal",
|
| 20 |
-
},
|
| 21 |
-
}
|
| 22 |
-
)
|
| 23 |
-
|
| 24 |
-
function ButtonGroup({
|
| 25 |
-
className,
|
| 26 |
-
orientation,
|
| 27 |
-
...props
|
| 28 |
-
}: React.ComponentProps<"div"> & VariantProps<typeof buttonGroupVariants>) {
|
| 29 |
-
return (
|
| 30 |
-
<div
|
| 31 |
-
role="group"
|
| 32 |
-
data-slot="button-group"
|
| 33 |
-
data-orientation={orientation}
|
| 34 |
-
className={cn(buttonGroupVariants({ orientation }), className)}
|
| 35 |
-
{...props}
|
| 36 |
-
/>
|
| 37 |
-
)
|
| 38 |
-
}
|
| 39 |
-
|
| 40 |
-
function ButtonGroupText({
|
| 41 |
-
className,
|
| 42 |
-
asChild = false,
|
| 43 |
-
...props
|
| 44 |
-
}: React.ComponentProps<"div"> & {
|
| 45 |
-
asChild?: boolean
|
| 46 |
-
}) {
|
| 47 |
-
const Comp = asChild ? Slot : "div"
|
| 48 |
-
|
| 49 |
-
return (
|
| 50 |
-
<Comp
|
| 51 |
-
className={cn(
|
| 52 |
-
"bg-muted shadow-xs flex items-center gap-2 rounded-md border px-4 text-sm font-medium [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none",
|
| 53 |
-
className
|
| 54 |
-
)}
|
| 55 |
-
{...props}
|
| 56 |
-
/>
|
| 57 |
-
)
|
| 58 |
-
}
|
| 59 |
-
|
| 60 |
-
function ButtonGroupSeparator({
|
| 61 |
-
className,
|
| 62 |
-
orientation = "vertical",
|
| 63 |
-
...props
|
| 64 |
-
}: React.ComponentProps<typeof Separator>) {
|
| 65 |
-
return (
|
| 66 |
-
<Separator
|
| 67 |
-
data-slot="button-group-separator"
|
| 68 |
-
orientation={orientation}
|
| 69 |
-
className={cn(
|
| 70 |
-
"bg-input relative !m-0 self-stretch data-[orientation=vertical]:h-auto",
|
| 71 |
-
className
|
| 72 |
-
)}
|
| 73 |
-
{...props}
|
| 74 |
-
/>
|
| 75 |
-
)
|
| 76 |
-
}
|
| 77 |
-
|
| 78 |
-
export {
|
| 79 |
-
ButtonGroup,
|
| 80 |
-
ButtonGroupSeparator,
|
| 81 |
-
ButtonGroupText,
|
| 82 |
-
buttonGroupVariants,
|
| 83 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/button.tsx
DELETED
|
@@ -1,58 +0,0 @@
|
|
| 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 "@/lib/utils"
|
| 6 |
-
|
| 7 |
-
const buttonVariants = cva(
|
| 8 |
-
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0" +
|
| 9 |
-
" hover-elevate active-elevate-2",
|
| 10 |
-
{
|
| 11 |
-
variants: {
|
| 12 |
-
variant: {
|
| 13 |
-
default:
|
| 14 |
-
"bg-primary text-primary-foreground border border-primary-border",
|
| 15 |
-
destructive:
|
| 16 |
-
"bg-destructive text-destructive-foreground shadow-sm border-destructive-border",
|
| 17 |
-
outline:
|
| 18 |
-
"border [border-color:var(--button-outline)] shadow-xs active:shadow-none",
|
| 19 |
-
secondary:
|
| 20 |
-
"border bg-secondary text-secondary-foreground border border-secondary-border",
|
| 21 |
-
ghost: "border border-transparent",
|
| 22 |
-
link: "text-primary underline-offset-4 hover:underline",
|
| 23 |
-
},
|
| 24 |
-
size: {
|
| 25 |
-
default: "min-h-9 px-4 py-2",
|
| 26 |
-
sm: "min-h-8 rounded-md px-3 text-xs",
|
| 27 |
-
lg: "min-h-10 rounded-md px-8",
|
| 28 |
-
icon: "h-9 w-9",
|
| 29 |
-
},
|
| 30 |
-
},
|
| 31 |
-
defaultVariants: {
|
| 32 |
-
variant: "default",
|
| 33 |
-
size: "default",
|
| 34 |
-
},
|
| 35 |
-
}
|
| 36 |
-
)
|
| 37 |
-
|
| 38 |
-
export interface ButtonProps
|
| 39 |
-
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
|
| 40 |
-
VariantProps<typeof buttonVariants> {
|
| 41 |
-
asChild?: boolean
|
| 42 |
-
}
|
| 43 |
-
|
| 44 |
-
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
| 45 |
-
({ className, variant, size, asChild = false, ...props }, ref) => {
|
| 46 |
-
const Comp = asChild ? Slot : "button"
|
| 47 |
-
return (
|
| 48 |
-
<Comp
|
| 49 |
-
className={cn(buttonVariants({ variant, size, className }))}
|
| 50 |
-
ref={ref}
|
| 51 |
-
{...props}
|
| 52 |
-
/>
|
| 53 |
-
)
|
| 54 |
-
}
|
| 55 |
-
)
|
| 56 |
-
Button.displayName = "Button"
|
| 57 |
-
|
| 58 |
-
export { Button, buttonVariants }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/calendar.tsx
DELETED
|
@@ -1,213 +0,0 @@
|
|
| 1 |
-
"use client"
|
| 2 |
-
|
| 3 |
-
import * as React from "react"
|
| 4 |
-
import {
|
| 5 |
-
ChevronDownIcon,
|
| 6 |
-
ChevronLeftIcon,
|
| 7 |
-
ChevronRightIcon,
|
| 8 |
-
} from "lucide-react"
|
| 9 |
-
import { DayButton, DayPicker, getDefaultClassNames } from "react-day-picker"
|
| 10 |
-
|
| 11 |
-
import { cn } from "@/lib/utils"
|
| 12 |
-
import { Button, buttonVariants } from "@/components/ui/button"
|
| 13 |
-
|
| 14 |
-
function Calendar({
|
| 15 |
-
className,
|
| 16 |
-
classNames,
|
| 17 |
-
showOutsideDays = true,
|
| 18 |
-
captionLayout = "label",
|
| 19 |
-
buttonVariant = "ghost",
|
| 20 |
-
formatters,
|
| 21 |
-
components,
|
| 22 |
-
...props
|
| 23 |
-
}: React.ComponentProps<typeof DayPicker> & {
|
| 24 |
-
buttonVariant?: React.ComponentProps<typeof Button>["variant"]
|
| 25 |
-
}) {
|
| 26 |
-
const defaultClassNames = getDefaultClassNames()
|
| 27 |
-
|
| 28 |
-
return (
|
| 29 |
-
<DayPicker
|
| 30 |
-
showOutsideDays={showOutsideDays}
|
| 31 |
-
className={cn(
|
| 32 |
-
"bg-background group/calendar p-3 [--cell-size:2rem] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
|
| 33 |
-
String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
|
| 34 |
-
String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
|
| 35 |
-
className
|
| 36 |
-
)}
|
| 37 |
-
captionLayout={captionLayout}
|
| 38 |
-
formatters={{
|
| 39 |
-
formatMonthDropdown: (date) =>
|
| 40 |
-
date.toLocaleString("default", { month: "short" }),
|
| 41 |
-
...formatters,
|
| 42 |
-
}}
|
| 43 |
-
classNames={{
|
| 44 |
-
root: cn("w-fit", defaultClassNames.root),
|
| 45 |
-
months: cn(
|
| 46 |
-
"relative flex flex-col gap-4 md:flex-row",
|
| 47 |
-
defaultClassNames.months
|
| 48 |
-
),
|
| 49 |
-
month: cn("flex w-full flex-col gap-4", defaultClassNames.month),
|
| 50 |
-
nav: cn(
|
| 51 |
-
"absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1",
|
| 52 |
-
defaultClassNames.nav
|
| 53 |
-
),
|
| 54 |
-
button_previous: cn(
|
| 55 |
-
buttonVariants({ variant: buttonVariant }),
|
| 56 |
-
"h-[--cell-size] w-[--cell-size] select-none p-0 aria-disabled:opacity-50",
|
| 57 |
-
defaultClassNames.button_previous
|
| 58 |
-
),
|
| 59 |
-
button_next: cn(
|
| 60 |
-
buttonVariants({ variant: buttonVariant }),
|
| 61 |
-
"h-[--cell-size] w-[--cell-size] select-none p-0 aria-disabled:opacity-50",
|
| 62 |
-
defaultClassNames.button_next
|
| 63 |
-
),
|
| 64 |
-
month_caption: cn(
|
| 65 |
-
"flex h-[--cell-size] w-full items-center justify-center px-[--cell-size]",
|
| 66 |
-
defaultClassNames.month_caption
|
| 67 |
-
),
|
| 68 |
-
dropdowns: cn(
|
| 69 |
-
"flex h-[--cell-size] w-full items-center justify-center gap-1.5 text-sm font-medium",
|
| 70 |
-
defaultClassNames.dropdowns
|
| 71 |
-
),
|
| 72 |
-
dropdown_root: cn(
|
| 73 |
-
"has-focus:border-ring border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] relative rounded-md border",
|
| 74 |
-
defaultClassNames.dropdown_root
|
| 75 |
-
),
|
| 76 |
-
dropdown: cn(
|
| 77 |
-
"bg-popover absolute inset-0 opacity-0",
|
| 78 |
-
defaultClassNames.dropdown
|
| 79 |
-
),
|
| 80 |
-
caption_label: cn(
|
| 81 |
-
"select-none font-medium",
|
| 82 |
-
captionLayout === "label"
|
| 83 |
-
? "text-sm"
|
| 84 |
-
: "[&>svg]:text-muted-foreground flex h-8 items-center gap-1 rounded-md pl-2 pr-1 text-sm [&>svg]:size-3.5",
|
| 85 |
-
defaultClassNames.caption_label
|
| 86 |
-
),
|
| 87 |
-
table: "w-full border-collapse",
|
| 88 |
-
weekdays: cn("flex", defaultClassNames.weekdays),
|
| 89 |
-
weekday: cn(
|
| 90 |
-
"text-muted-foreground flex-1 select-none rounded-md text-[0.8rem] font-normal",
|
| 91 |
-
defaultClassNames.weekday
|
| 92 |
-
),
|
| 93 |
-
week: cn("mt-2 flex w-full", defaultClassNames.week),
|
| 94 |
-
week_number_header: cn(
|
| 95 |
-
"w-[--cell-size] select-none",
|
| 96 |
-
defaultClassNames.week_number_header
|
| 97 |
-
),
|
| 98 |
-
week_number: cn(
|
| 99 |
-
"text-muted-foreground select-none text-[0.8rem]",
|
| 100 |
-
defaultClassNames.week_number
|
| 101 |
-
),
|
| 102 |
-
day: cn(
|
| 103 |
-
"group/day relative aspect-square h-full w-full select-none p-0 text-center [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md",
|
| 104 |
-
defaultClassNames.day
|
| 105 |
-
),
|
| 106 |
-
range_start: cn(
|
| 107 |
-
"bg-accent rounded-l-md",
|
| 108 |
-
defaultClassNames.range_start
|
| 109 |
-
),
|
| 110 |
-
range_middle: cn("rounded-none", defaultClassNames.range_middle),
|
| 111 |
-
range_end: cn("bg-accent rounded-r-md", defaultClassNames.range_end),
|
| 112 |
-
today: cn(
|
| 113 |
-
"bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none",
|
| 114 |
-
defaultClassNames.today
|
| 115 |
-
),
|
| 116 |
-
outside: cn(
|
| 117 |
-
"text-muted-foreground aria-selected:text-muted-foreground",
|
| 118 |
-
defaultClassNames.outside
|
| 119 |
-
),
|
| 120 |
-
disabled: cn(
|
| 121 |
-
"text-muted-foreground opacity-50",
|
| 122 |
-
defaultClassNames.disabled
|
| 123 |
-
),
|
| 124 |
-
hidden: cn("invisible", defaultClassNames.hidden),
|
| 125 |
-
...classNames,
|
| 126 |
-
}}
|
| 127 |
-
components={{
|
| 128 |
-
Root: ({ className, rootRef, ...props }) => {
|
| 129 |
-
return (
|
| 130 |
-
<div
|
| 131 |
-
data-slot="calendar"
|
| 132 |
-
ref={rootRef}
|
| 133 |
-
className={cn(className)}
|
| 134 |
-
{...props}
|
| 135 |
-
/>
|
| 136 |
-
)
|
| 137 |
-
},
|
| 138 |
-
Chevron: ({ className, orientation, ...props }) => {
|
| 139 |
-
if (orientation === "left") {
|
| 140 |
-
return (
|
| 141 |
-
<ChevronLeftIcon className={cn("size-4", className)} {...props} />
|
| 142 |
-
)
|
| 143 |
-
}
|
| 144 |
-
|
| 145 |
-
if (orientation === "right") {
|
| 146 |
-
return (
|
| 147 |
-
<ChevronRightIcon
|
| 148 |
-
className={cn("size-4", className)}
|
| 149 |
-
{...props}
|
| 150 |
-
/>
|
| 151 |
-
)
|
| 152 |
-
}
|
| 153 |
-
|
| 154 |
-
return (
|
| 155 |
-
<ChevronDownIcon className={cn("size-4", className)} {...props} />
|
| 156 |
-
)
|
| 157 |
-
},
|
| 158 |
-
DayButton: CalendarDayButton,
|
| 159 |
-
WeekNumber: ({ children, ...props }) => {
|
| 160 |
-
return (
|
| 161 |
-
<td {...props}>
|
| 162 |
-
<div className="flex size-[--cell-size] items-center justify-center text-center">
|
| 163 |
-
{children}
|
| 164 |
-
</div>
|
| 165 |
-
</td>
|
| 166 |
-
)
|
| 167 |
-
},
|
| 168 |
-
...components,
|
| 169 |
-
}}
|
| 170 |
-
{...props}
|
| 171 |
-
/>
|
| 172 |
-
)
|
| 173 |
-
}
|
| 174 |
-
|
| 175 |
-
function CalendarDayButton({
|
| 176 |
-
className,
|
| 177 |
-
day,
|
| 178 |
-
modifiers,
|
| 179 |
-
...props
|
| 180 |
-
}: React.ComponentProps<typeof DayButton>) {
|
| 181 |
-
const defaultClassNames = getDefaultClassNames()
|
| 182 |
-
|
| 183 |
-
const ref = React.useRef<HTMLButtonElement>(null)
|
| 184 |
-
React.useEffect(() => {
|
| 185 |
-
if (modifiers.focused) ref.current?.focus()
|
| 186 |
-
}, [modifiers.focused])
|
| 187 |
-
|
| 188 |
-
return (
|
| 189 |
-
<Button
|
| 190 |
-
ref={ref}
|
| 191 |
-
variant="ghost"
|
| 192 |
-
size="icon"
|
| 193 |
-
data-day={day.date.toLocaleDateString()}
|
| 194 |
-
data-selected-single={
|
| 195 |
-
modifiers.selected &&
|
| 196 |
-
!modifiers.range_start &&
|
| 197 |
-
!modifiers.range_end &&
|
| 198 |
-
!modifiers.range_middle
|
| 199 |
-
}
|
| 200 |
-
data-range-start={modifiers.range_start}
|
| 201 |
-
data-range-end={modifiers.range_end}
|
| 202 |
-
data-range-middle={modifiers.range_middle}
|
| 203 |
-
className={cn(
|
| 204 |
-
"data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-ring/50 flex aspect-square h-auto w-full min-w-[--cell-size] flex-col gap-1 font-normal leading-none data-[range-end=true]:rounded-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] [&>span]:text-xs [&>span]:opacity-70",
|
| 205 |
-
defaultClassNames.day,
|
| 206 |
-
className
|
| 207 |
-
)}
|
| 208 |
-
{...props}
|
| 209 |
-
/>
|
| 210 |
-
)
|
| 211 |
-
}
|
| 212 |
-
|
| 213 |
-
export { Calendar, CalendarDayButton }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/card.tsx
DELETED
|
@@ -1,76 +0,0 @@
|
|
| 1 |
-
import * as React from "react"
|
| 2 |
-
|
| 3 |
-
import { cn } from "@/lib/utils"
|
| 4 |
-
|
| 5 |
-
const Card = React.forwardRef<
|
| 6 |
-
HTMLDivElement,
|
| 7 |
-
React.HTMLAttributes<HTMLDivElement>
|
| 8 |
-
>(({ className, ...props }, ref) => (
|
| 9 |
-
<div
|
| 10 |
-
ref={ref}
|
| 11 |
-
className={cn(
|
| 12 |
-
"rounded-xl border bg-card text-card-foreground shadow",
|
| 13 |
-
className
|
| 14 |
-
)}
|
| 15 |
-
{...props}
|
| 16 |
-
/>
|
| 17 |
-
))
|
| 18 |
-
Card.displayName = "Card"
|
| 19 |
-
|
| 20 |
-
const CardHeader = React.forwardRef<
|
| 21 |
-
HTMLDivElement,
|
| 22 |
-
React.HTMLAttributes<HTMLDivElement>
|
| 23 |
-
>(({ className, ...props }, ref) => (
|
| 24 |
-
<div
|
| 25 |
-
ref={ref}
|
| 26 |
-
className={cn("flex flex-col space-y-1.5 p-6", className)}
|
| 27 |
-
{...props}
|
| 28 |
-
/>
|
| 29 |
-
))
|
| 30 |
-
CardHeader.displayName = "CardHeader"
|
| 31 |
-
|
| 32 |
-
const CardTitle = React.forwardRef<
|
| 33 |
-
HTMLDivElement,
|
| 34 |
-
React.HTMLAttributes<HTMLDivElement>
|
| 35 |
-
>(({ className, ...props }, ref) => (
|
| 36 |
-
<div
|
| 37 |
-
ref={ref}
|
| 38 |
-
className={cn("font-semibold leading-none tracking-tight", className)}
|
| 39 |
-
{...props}
|
| 40 |
-
/>
|
| 41 |
-
))
|
| 42 |
-
CardTitle.displayName = "CardTitle"
|
| 43 |
-
|
| 44 |
-
const CardDescription = React.forwardRef<
|
| 45 |
-
HTMLDivElement,
|
| 46 |
-
React.HTMLAttributes<HTMLDivElement>
|
| 47 |
-
>(({ className, ...props }, ref) => (
|
| 48 |
-
<div
|
| 49 |
-
ref={ref}
|
| 50 |
-
className={cn("text-sm text-muted-foreground", className)}
|
| 51 |
-
{...props}
|
| 52 |
-
/>
|
| 53 |
-
))
|
| 54 |
-
CardDescription.displayName = "CardDescription"
|
| 55 |
-
|
| 56 |
-
const CardContent = React.forwardRef<
|
| 57 |
-
HTMLDivElement,
|
| 58 |
-
React.HTMLAttributes<HTMLDivElement>
|
| 59 |
-
>(({ className, ...props }, ref) => (
|
| 60 |
-
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
|
| 61 |
-
))
|
| 62 |
-
CardContent.displayName = "CardContent"
|
| 63 |
-
|
| 64 |
-
const CardFooter = React.forwardRef<
|
| 65 |
-
HTMLDivElement,
|
| 66 |
-
React.HTMLAttributes<HTMLDivElement>
|
| 67 |
-
>(({ className, ...props }, ref) => (
|
| 68 |
-
<div
|
| 69 |
-
ref={ref}
|
| 70 |
-
className={cn("flex items-center p-6 pt-0", className)}
|
| 71 |
-
{...props}
|
| 72 |
-
/>
|
| 73 |
-
))
|
| 74 |
-
CardFooter.displayName = "CardFooter"
|
| 75 |
-
|
| 76 |
-
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/carousel.tsx
DELETED
|
@@ -1,260 +0,0 @@
|
|
| 1 |
-
import * as React from "react"
|
| 2 |
-
import useEmblaCarousel, {
|
| 3 |
-
type UseEmblaCarouselType,
|
| 4 |
-
} from "embla-carousel-react"
|
| 5 |
-
import { ArrowLeft, ArrowRight } from "lucide-react"
|
| 6 |
-
|
| 7 |
-
import { cn } from "@/lib/utils"
|
| 8 |
-
import { Button } from "@/components/ui/button"
|
| 9 |
-
|
| 10 |
-
type CarouselApi = UseEmblaCarouselType[1]
|
| 11 |
-
type UseCarouselParameters = Parameters<typeof useEmblaCarousel>
|
| 12 |
-
type CarouselOptions = UseCarouselParameters[0]
|
| 13 |
-
type CarouselPlugin = UseCarouselParameters[1]
|
| 14 |
-
|
| 15 |
-
type CarouselProps = {
|
| 16 |
-
opts?: CarouselOptions
|
| 17 |
-
plugins?: CarouselPlugin
|
| 18 |
-
orientation?: "horizontal" | "vertical"
|
| 19 |
-
setApi?: (api: CarouselApi) => void
|
| 20 |
-
}
|
| 21 |
-
|
| 22 |
-
type CarouselContextProps = {
|
| 23 |
-
carouselRef: ReturnType<typeof useEmblaCarousel>[0]
|
| 24 |
-
api: ReturnType<typeof useEmblaCarousel>[1]
|
| 25 |
-
scrollPrev: () => void
|
| 26 |
-
scrollNext: () => void
|
| 27 |
-
canScrollPrev: boolean
|
| 28 |
-
canScrollNext: boolean
|
| 29 |
-
} & CarouselProps
|
| 30 |
-
|
| 31 |
-
const CarouselContext = React.createContext<CarouselContextProps | null>(null)
|
| 32 |
-
|
| 33 |
-
function useCarousel() {
|
| 34 |
-
const context = React.useContext(CarouselContext)
|
| 35 |
-
|
| 36 |
-
if (!context) {
|
| 37 |
-
throw new Error("useCarousel must be used within a <Carousel />")
|
| 38 |
-
}
|
| 39 |
-
|
| 40 |
-
return context
|
| 41 |
-
}
|
| 42 |
-
|
| 43 |
-
const Carousel = React.forwardRef<
|
| 44 |
-
HTMLDivElement,
|
| 45 |
-
React.HTMLAttributes<HTMLDivElement> & CarouselProps
|
| 46 |
-
>(
|
| 47 |
-
(
|
| 48 |
-
{
|
| 49 |
-
orientation = "horizontal",
|
| 50 |
-
opts,
|
| 51 |
-
setApi,
|
| 52 |
-
plugins,
|
| 53 |
-
className,
|
| 54 |
-
children,
|
| 55 |
-
...props
|
| 56 |
-
},
|
| 57 |
-
ref
|
| 58 |
-
) => {
|
| 59 |
-
const [carouselRef, api] = useEmblaCarousel(
|
| 60 |
-
{
|
| 61 |
-
...opts,
|
| 62 |
-
axis: orientation === "horizontal" ? "x" : "y",
|
| 63 |
-
},
|
| 64 |
-
plugins
|
| 65 |
-
)
|
| 66 |
-
const [canScrollPrev, setCanScrollPrev] = React.useState(false)
|
| 67 |
-
const [canScrollNext, setCanScrollNext] = React.useState(false)
|
| 68 |
-
|
| 69 |
-
const onSelect = React.useCallback((api: CarouselApi) => {
|
| 70 |
-
if (!api) {
|
| 71 |
-
return
|
| 72 |
-
}
|
| 73 |
-
|
| 74 |
-
setCanScrollPrev(api.canScrollPrev())
|
| 75 |
-
setCanScrollNext(api.canScrollNext())
|
| 76 |
-
}, [])
|
| 77 |
-
|
| 78 |
-
const scrollPrev = React.useCallback(() => {
|
| 79 |
-
api?.scrollPrev()
|
| 80 |
-
}, [api])
|
| 81 |
-
|
| 82 |
-
const scrollNext = React.useCallback(() => {
|
| 83 |
-
api?.scrollNext()
|
| 84 |
-
}, [api])
|
| 85 |
-
|
| 86 |
-
const handleKeyDown = React.useCallback(
|
| 87 |
-
(event: React.KeyboardEvent<HTMLDivElement>) => {
|
| 88 |
-
if (event.key === "ArrowLeft") {
|
| 89 |
-
event.preventDefault()
|
| 90 |
-
scrollPrev()
|
| 91 |
-
} else if (event.key === "ArrowRight") {
|
| 92 |
-
event.preventDefault()
|
| 93 |
-
scrollNext()
|
| 94 |
-
}
|
| 95 |
-
},
|
| 96 |
-
[scrollPrev, scrollNext]
|
| 97 |
-
)
|
| 98 |
-
|
| 99 |
-
React.useEffect(() => {
|
| 100 |
-
if (!api || !setApi) {
|
| 101 |
-
return
|
| 102 |
-
}
|
| 103 |
-
|
| 104 |
-
setApi(api)
|
| 105 |
-
}, [api, setApi])
|
| 106 |
-
|
| 107 |
-
React.useEffect(() => {
|
| 108 |
-
if (!api) {
|
| 109 |
-
return
|
| 110 |
-
}
|
| 111 |
-
|
| 112 |
-
onSelect(api)
|
| 113 |
-
api.on("reInit", onSelect)
|
| 114 |
-
api.on("select", onSelect)
|
| 115 |
-
|
| 116 |
-
return () => {
|
| 117 |
-
api?.off("select", onSelect)
|
| 118 |
-
}
|
| 119 |
-
}, [api, onSelect])
|
| 120 |
-
|
| 121 |
-
return (
|
| 122 |
-
<CarouselContext.Provider
|
| 123 |
-
value={{
|
| 124 |
-
carouselRef,
|
| 125 |
-
api: api,
|
| 126 |
-
opts,
|
| 127 |
-
orientation:
|
| 128 |
-
orientation || (opts?.axis === "y" ? "vertical" : "horizontal"),
|
| 129 |
-
scrollPrev,
|
| 130 |
-
scrollNext,
|
| 131 |
-
canScrollPrev,
|
| 132 |
-
canScrollNext,
|
| 133 |
-
}}
|
| 134 |
-
>
|
| 135 |
-
<div
|
| 136 |
-
ref={ref}
|
| 137 |
-
onKeyDownCapture={handleKeyDown}
|
| 138 |
-
className={cn("relative", className)}
|
| 139 |
-
role="region"
|
| 140 |
-
aria-roledescription="carousel"
|
| 141 |
-
{...props}
|
| 142 |
-
>
|
| 143 |
-
{children}
|
| 144 |
-
</div>
|
| 145 |
-
</CarouselContext.Provider>
|
| 146 |
-
)
|
| 147 |
-
}
|
| 148 |
-
)
|
| 149 |
-
Carousel.displayName = "Carousel"
|
| 150 |
-
|
| 151 |
-
const CarouselContent = React.forwardRef<
|
| 152 |
-
HTMLDivElement,
|
| 153 |
-
React.HTMLAttributes<HTMLDivElement>
|
| 154 |
-
>(({ className, ...props }, ref) => {
|
| 155 |
-
const { carouselRef, orientation } = useCarousel()
|
| 156 |
-
|
| 157 |
-
return (
|
| 158 |
-
<div ref={carouselRef} className="overflow-hidden">
|
| 159 |
-
<div
|
| 160 |
-
ref={ref}
|
| 161 |
-
className={cn(
|
| 162 |
-
"flex",
|
| 163 |
-
orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col",
|
| 164 |
-
className
|
| 165 |
-
)}
|
| 166 |
-
{...props}
|
| 167 |
-
/>
|
| 168 |
-
</div>
|
| 169 |
-
)
|
| 170 |
-
})
|
| 171 |
-
CarouselContent.displayName = "CarouselContent"
|
| 172 |
-
|
| 173 |
-
const CarouselItem = React.forwardRef<
|
| 174 |
-
HTMLDivElement,
|
| 175 |
-
React.HTMLAttributes<HTMLDivElement>
|
| 176 |
-
>(({ className, ...props }, ref) => {
|
| 177 |
-
const { orientation } = useCarousel()
|
| 178 |
-
|
| 179 |
-
return (
|
| 180 |
-
<div
|
| 181 |
-
ref={ref}
|
| 182 |
-
role="group"
|
| 183 |
-
aria-roledescription="slide"
|
| 184 |
-
className={cn(
|
| 185 |
-
"min-w-0 shrink-0 grow-0 basis-full",
|
| 186 |
-
orientation === "horizontal" ? "pl-4" : "pt-4",
|
| 187 |
-
className
|
| 188 |
-
)}
|
| 189 |
-
{...props}
|
| 190 |
-
/>
|
| 191 |
-
)
|
| 192 |
-
})
|
| 193 |
-
CarouselItem.displayName = "CarouselItem"
|
| 194 |
-
|
| 195 |
-
const CarouselPrevious = React.forwardRef<
|
| 196 |
-
HTMLButtonElement,
|
| 197 |
-
React.ComponentProps<typeof Button>
|
| 198 |
-
>(({ className, variant = "outline", size = "icon", ...props }, ref) => {
|
| 199 |
-
const { orientation, scrollPrev, canScrollPrev } = useCarousel()
|
| 200 |
-
|
| 201 |
-
return (
|
| 202 |
-
<Button
|
| 203 |
-
ref={ref}
|
| 204 |
-
variant={variant}
|
| 205 |
-
size={size}
|
| 206 |
-
className={cn(
|
| 207 |
-
"absolute h-8 w-8 rounded-full",
|
| 208 |
-
orientation === "horizontal"
|
| 209 |
-
? "-left-12 top-1/2 -translate-y-1/2"
|
| 210 |
-
: "-top-12 left-1/2 -translate-x-1/2 rotate-90",
|
| 211 |
-
className
|
| 212 |
-
)}
|
| 213 |
-
disabled={!canScrollPrev}
|
| 214 |
-
onClick={scrollPrev}
|
| 215 |
-
{...props}
|
| 216 |
-
>
|
| 217 |
-
<ArrowLeft className="h-4 w-4" />
|
| 218 |
-
<span className="sr-only">Previous slide</span>
|
| 219 |
-
</Button>
|
| 220 |
-
)
|
| 221 |
-
})
|
| 222 |
-
CarouselPrevious.displayName = "CarouselPrevious"
|
| 223 |
-
|
| 224 |
-
const CarouselNext = React.forwardRef<
|
| 225 |
-
HTMLButtonElement,
|
| 226 |
-
React.ComponentProps<typeof Button>
|
| 227 |
-
>(({ className, variant = "outline", size = "icon", ...props }, ref) => {
|
| 228 |
-
const { orientation, scrollNext, canScrollNext } = useCarousel()
|
| 229 |
-
|
| 230 |
-
return (
|
| 231 |
-
<Button
|
| 232 |
-
ref={ref}
|
| 233 |
-
variant={variant}
|
| 234 |
-
size={size}
|
| 235 |
-
className={cn(
|
| 236 |
-
"absolute h-8 w-8 rounded-full",
|
| 237 |
-
orientation === "horizontal"
|
| 238 |
-
? "-right-12 top-1/2 -translate-y-1/2"
|
| 239 |
-
: "-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
|
| 240 |
-
className
|
| 241 |
-
)}
|
| 242 |
-
disabled={!canScrollNext}
|
| 243 |
-
onClick={scrollNext}
|
| 244 |
-
{...props}
|
| 245 |
-
>
|
| 246 |
-
<ArrowRight className="h-4 w-4" />
|
| 247 |
-
<span className="sr-only">Next slide</span>
|
| 248 |
-
</Button>
|
| 249 |
-
)
|
| 250 |
-
})
|
| 251 |
-
CarouselNext.displayName = "CarouselNext"
|
| 252 |
-
|
| 253 |
-
export {
|
| 254 |
-
type CarouselApi,
|
| 255 |
-
Carousel,
|
| 256 |
-
CarouselContent,
|
| 257 |
-
CarouselItem,
|
| 258 |
-
CarouselPrevious,
|
| 259 |
-
CarouselNext,
|
| 260 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/chart.tsx
DELETED
|
@@ -1,365 +0,0 @@
|
|
| 1 |
-
import * as React from "react"
|
| 2 |
-
import * as RechartsPrimitive from "recharts"
|
| 3 |
-
|
| 4 |
-
import { cn } from "@/lib/utils"
|
| 5 |
-
|
| 6 |
-
const THEMES = { light: "", dark: ".dark" } as const
|
| 7 |
-
|
| 8 |
-
export type ChartConfig = {
|
| 9 |
-
[k in string]: {
|
| 10 |
-
label?: React.ReactNode
|
| 11 |
-
icon?: React.ComponentType
|
| 12 |
-
} & (
|
| 13 |
-
| { color?: string; theme?: never }
|
| 14 |
-
| { color?: never; theme: Record<keyof typeof THEMES, string> }
|
| 15 |
-
)
|
| 16 |
-
}
|
| 17 |
-
|
| 18 |
-
type ChartContextProps = {
|
| 19 |
-
config: ChartConfig
|
| 20 |
-
}
|
| 21 |
-
|
| 22 |
-
const ChartContext = React.createContext<ChartContextProps | null>(null)
|
| 23 |
-
|
| 24 |
-
function useChart() {
|
| 25 |
-
const context = React.useContext(ChartContext)
|
| 26 |
-
|
| 27 |
-
if (!context) {
|
| 28 |
-
throw new Error("useChart must be used within a <ChartContainer />")
|
| 29 |
-
}
|
| 30 |
-
|
| 31 |
-
return context
|
| 32 |
-
}
|
| 33 |
-
|
| 34 |
-
const ChartContainer = React.forwardRef<
|
| 35 |
-
HTMLDivElement,
|
| 36 |
-
React.ComponentProps<"div"> & {
|
| 37 |
-
config: ChartConfig
|
| 38 |
-
children: React.ComponentProps<
|
| 39 |
-
typeof RechartsPrimitive.ResponsiveContainer
|
| 40 |
-
>["children"]
|
| 41 |
-
}
|
| 42 |
-
>(({ id, className, children, config, ...props }, ref) => {
|
| 43 |
-
const uniqueId = React.useId()
|
| 44 |
-
const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`
|
| 45 |
-
|
| 46 |
-
return (
|
| 47 |
-
<ChartContext.Provider value={{ config }}>
|
| 48 |
-
<div
|
| 49 |
-
data-chart={chartId}
|
| 50 |
-
ref={ref}
|
| 51 |
-
className={cn(
|
| 52 |
-
"flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-none [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-sector]:outline-none [&_.recharts-surface]:outline-none",
|
| 53 |
-
className
|
| 54 |
-
)}
|
| 55 |
-
{...props}
|
| 56 |
-
>
|
| 57 |
-
<ChartStyle id={chartId} config={config} />
|
| 58 |
-
<RechartsPrimitive.ResponsiveContainer>
|
| 59 |
-
{children}
|
| 60 |
-
</RechartsPrimitive.ResponsiveContainer>
|
| 61 |
-
</div>
|
| 62 |
-
</ChartContext.Provider>
|
| 63 |
-
)
|
| 64 |
-
})
|
| 65 |
-
ChartContainer.displayName = "Chart"
|
| 66 |
-
|
| 67 |
-
const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {
|
| 68 |
-
const colorConfig = Object.entries(config).filter(
|
| 69 |
-
([, config]) => config.theme || config.color
|
| 70 |
-
)
|
| 71 |
-
|
| 72 |
-
if (!colorConfig.length) {
|
| 73 |
-
return null
|
| 74 |
-
}
|
| 75 |
-
|
| 76 |
-
return (
|
| 77 |
-
<style
|
| 78 |
-
dangerouslySetInnerHTML={{
|
| 79 |
-
__html: Object.entries(THEMES)
|
| 80 |
-
.map(
|
| 81 |
-
([theme, prefix]) => `
|
| 82 |
-
${prefix} [data-chart=${id}] {
|
| 83 |
-
${colorConfig
|
| 84 |
-
.map(([key, itemConfig]) => {
|
| 85 |
-
const color =
|
| 86 |
-
itemConfig.theme?.[theme as keyof typeof itemConfig.theme] ||
|
| 87 |
-
itemConfig.color
|
| 88 |
-
return color ? ` --color-${key}: ${color};` : null
|
| 89 |
-
})
|
| 90 |
-
.join("\n")}
|
| 91 |
-
}
|
| 92 |
-
`
|
| 93 |
-
)
|
| 94 |
-
.join("\n"),
|
| 95 |
-
}}
|
| 96 |
-
/>
|
| 97 |
-
)
|
| 98 |
-
}
|
| 99 |
-
|
| 100 |
-
const ChartTooltip = RechartsPrimitive.Tooltip
|
| 101 |
-
|
| 102 |
-
const ChartTooltipContent = React.forwardRef<
|
| 103 |
-
HTMLDivElement,
|
| 104 |
-
React.ComponentProps<typeof RechartsPrimitive.Tooltip> &
|
| 105 |
-
React.ComponentProps<"div"> & {
|
| 106 |
-
hideLabel?: boolean
|
| 107 |
-
hideIndicator?: boolean
|
| 108 |
-
indicator?: "line" | "dot" | "dashed"
|
| 109 |
-
nameKey?: string
|
| 110 |
-
labelKey?: string
|
| 111 |
-
}
|
| 112 |
-
>(
|
| 113 |
-
(
|
| 114 |
-
{
|
| 115 |
-
active,
|
| 116 |
-
payload,
|
| 117 |
-
className,
|
| 118 |
-
indicator = "dot",
|
| 119 |
-
hideLabel = false,
|
| 120 |
-
hideIndicator = false,
|
| 121 |
-
label,
|
| 122 |
-
labelFormatter,
|
| 123 |
-
labelClassName,
|
| 124 |
-
formatter,
|
| 125 |
-
color,
|
| 126 |
-
nameKey,
|
| 127 |
-
labelKey,
|
| 128 |
-
},
|
| 129 |
-
ref
|
| 130 |
-
) => {
|
| 131 |
-
const { config } = useChart()
|
| 132 |
-
|
| 133 |
-
const tooltipLabel = React.useMemo(() => {
|
| 134 |
-
if (hideLabel || !payload?.length) {
|
| 135 |
-
return null
|
| 136 |
-
}
|
| 137 |
-
|
| 138 |
-
const [item] = payload
|
| 139 |
-
const key = `${labelKey || item?.dataKey || item?.name || "value"}`
|
| 140 |
-
const itemConfig = getPayloadConfigFromPayload(config, item, key)
|
| 141 |
-
const value =
|
| 142 |
-
!labelKey && typeof label === "string"
|
| 143 |
-
? config[label as keyof typeof config]?.label || label
|
| 144 |
-
: itemConfig?.label
|
| 145 |
-
|
| 146 |
-
if (labelFormatter) {
|
| 147 |
-
return (
|
| 148 |
-
<div className={cn("font-medium", labelClassName)}>
|
| 149 |
-
{labelFormatter(value, payload)}
|
| 150 |
-
</div>
|
| 151 |
-
)
|
| 152 |
-
}
|
| 153 |
-
|
| 154 |
-
if (!value) {
|
| 155 |
-
return null
|
| 156 |
-
}
|
| 157 |
-
|
| 158 |
-
return <div className={cn("font-medium", labelClassName)}>{value}</div>
|
| 159 |
-
}, [
|
| 160 |
-
label,
|
| 161 |
-
labelFormatter,
|
| 162 |
-
payload,
|
| 163 |
-
hideLabel,
|
| 164 |
-
labelClassName,
|
| 165 |
-
config,
|
| 166 |
-
labelKey,
|
| 167 |
-
])
|
| 168 |
-
|
| 169 |
-
if (!active || !payload?.length) {
|
| 170 |
-
return null
|
| 171 |
-
}
|
| 172 |
-
|
| 173 |
-
const nestLabel = payload.length === 1 && indicator !== "dot"
|
| 174 |
-
|
| 175 |
-
return (
|
| 176 |
-
<div
|
| 177 |
-
ref={ref}
|
| 178 |
-
className={cn(
|
| 179 |
-
"grid min-w-[8rem] items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl",
|
| 180 |
-
className
|
| 181 |
-
)}
|
| 182 |
-
>
|
| 183 |
-
{!nestLabel ? tooltipLabel : null}
|
| 184 |
-
<div className="grid gap-1.5">
|
| 185 |
-
{payload
|
| 186 |
-
.filter((item) => item.type !== "none")
|
| 187 |
-
.map((item, index) => {
|
| 188 |
-
const key = `${nameKey || item.name || item.dataKey || "value"}`
|
| 189 |
-
const itemConfig = getPayloadConfigFromPayload(config, item, key)
|
| 190 |
-
const indicatorColor = color || item.payload.fill || item.color
|
| 191 |
-
|
| 192 |
-
return (
|
| 193 |
-
<div
|
| 194 |
-
key={item.dataKey}
|
| 195 |
-
className={cn(
|
| 196 |
-
"flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground",
|
| 197 |
-
indicator === "dot" && "items-center"
|
| 198 |
-
)}
|
| 199 |
-
>
|
| 200 |
-
{formatter && item?.value !== undefined && item.name ? (
|
| 201 |
-
formatter(item.value, item.name, item, index, item.payload)
|
| 202 |
-
) : (
|
| 203 |
-
<>
|
| 204 |
-
{itemConfig?.icon ? (
|
| 205 |
-
<itemConfig.icon />
|
| 206 |
-
) : (
|
| 207 |
-
!hideIndicator && (
|
| 208 |
-
<div
|
| 209 |
-
className={cn(
|
| 210 |
-
"shrink-0 rounded-[2px] border-[--color-border] bg-[--color-bg]",
|
| 211 |
-
{
|
| 212 |
-
"h-2.5 w-2.5": indicator === "dot",
|
| 213 |
-
"w-1": indicator === "line",
|
| 214 |
-
"w-0 border-[1.5px] border-dashed bg-transparent":
|
| 215 |
-
indicator === "dashed",
|
| 216 |
-
"my-0.5": nestLabel && indicator === "dashed",
|
| 217 |
-
}
|
| 218 |
-
)}
|
| 219 |
-
style={
|
| 220 |
-
{
|
| 221 |
-
"--color-bg": indicatorColor,
|
| 222 |
-
"--color-border": indicatorColor,
|
| 223 |
-
} as React.CSSProperties
|
| 224 |
-
}
|
| 225 |
-
/>
|
| 226 |
-
)
|
| 227 |
-
)}
|
| 228 |
-
<div
|
| 229 |
-
className={cn(
|
| 230 |
-
"flex flex-1 justify-between leading-none",
|
| 231 |
-
nestLabel ? "items-end" : "items-center"
|
| 232 |
-
)}
|
| 233 |
-
>
|
| 234 |
-
<div className="grid gap-1.5">
|
| 235 |
-
{nestLabel ? tooltipLabel : null}
|
| 236 |
-
<span className="text-muted-foreground">
|
| 237 |
-
{itemConfig?.label || item.name}
|
| 238 |
-
</span>
|
| 239 |
-
</div>
|
| 240 |
-
{item.value && (
|
| 241 |
-
<span className="font-mono font-medium tabular-nums text-foreground">
|
| 242 |
-
{item.value.toLocaleString()}
|
| 243 |
-
</span>
|
| 244 |
-
)}
|
| 245 |
-
</div>
|
| 246 |
-
</>
|
| 247 |
-
)}
|
| 248 |
-
</div>
|
| 249 |
-
)
|
| 250 |
-
})}
|
| 251 |
-
</div>
|
| 252 |
-
</div>
|
| 253 |
-
)
|
| 254 |
-
}
|
| 255 |
-
)
|
| 256 |
-
ChartTooltipContent.displayName = "ChartTooltip"
|
| 257 |
-
|
| 258 |
-
const ChartLegend = RechartsPrimitive.Legend
|
| 259 |
-
|
| 260 |
-
const ChartLegendContent = React.forwardRef<
|
| 261 |
-
HTMLDivElement,
|
| 262 |
-
React.ComponentProps<"div"> &
|
| 263 |
-
Pick<RechartsPrimitive.LegendProps, "payload" | "verticalAlign"> & {
|
| 264 |
-
hideIcon?: boolean
|
| 265 |
-
nameKey?: string
|
| 266 |
-
}
|
| 267 |
-
>(
|
| 268 |
-
(
|
| 269 |
-
{ className, hideIcon = false, payload, verticalAlign = "bottom", nameKey },
|
| 270 |
-
ref
|
| 271 |
-
) => {
|
| 272 |
-
const { config } = useChart()
|
| 273 |
-
|
| 274 |
-
if (!payload?.length) {
|
| 275 |
-
return null
|
| 276 |
-
}
|
| 277 |
-
|
| 278 |
-
return (
|
| 279 |
-
<div
|
| 280 |
-
ref={ref}
|
| 281 |
-
className={cn(
|
| 282 |
-
"flex items-center justify-center gap-4",
|
| 283 |
-
verticalAlign === "top" ? "pb-3" : "pt-3",
|
| 284 |
-
className
|
| 285 |
-
)}
|
| 286 |
-
>
|
| 287 |
-
{payload
|
| 288 |
-
.filter((item) => item.type !== "none")
|
| 289 |
-
.map((item) => {
|
| 290 |
-
const key = `${nameKey || item.dataKey || "value"}`
|
| 291 |
-
const itemConfig = getPayloadConfigFromPayload(config, item, key)
|
| 292 |
-
|
| 293 |
-
return (
|
| 294 |
-
<div
|
| 295 |
-
key={item.value}
|
| 296 |
-
className={cn(
|
| 297 |
-
"flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground"
|
| 298 |
-
)}
|
| 299 |
-
>
|
| 300 |
-
{itemConfig?.icon && !hideIcon ? (
|
| 301 |
-
<itemConfig.icon />
|
| 302 |
-
) : (
|
| 303 |
-
<div
|
| 304 |
-
className="h-2 w-2 shrink-0 rounded-[2px]"
|
| 305 |
-
style={{
|
| 306 |
-
backgroundColor: item.color,
|
| 307 |
-
}}
|
| 308 |
-
/>
|
| 309 |
-
)}
|
| 310 |
-
{itemConfig?.label}
|
| 311 |
-
</div>
|
| 312 |
-
)
|
| 313 |
-
})}
|
| 314 |
-
</div>
|
| 315 |
-
)
|
| 316 |
-
}
|
| 317 |
-
)
|
| 318 |
-
ChartLegendContent.displayName = "ChartLegend"
|
| 319 |
-
|
| 320 |
-
function getPayloadConfigFromPayload(
|
| 321 |
-
config: ChartConfig,
|
| 322 |
-
payload: unknown,
|
| 323 |
-
key: string
|
| 324 |
-
) {
|
| 325 |
-
if (typeof payload !== "object" || payload === null) {
|
| 326 |
-
return undefined
|
| 327 |
-
}
|
| 328 |
-
|
| 329 |
-
const payloadPayload =
|
| 330 |
-
"payload" in payload &&
|
| 331 |
-
typeof payload.payload === "object" &&
|
| 332 |
-
payload.payload !== null
|
| 333 |
-
? payload.payload
|
| 334 |
-
: undefined
|
| 335 |
-
|
| 336 |
-
let configLabelKey: string = key
|
| 337 |
-
|
| 338 |
-
if (
|
| 339 |
-
key in payload &&
|
| 340 |
-
typeof payload[key as keyof typeof payload] === "string"
|
| 341 |
-
) {
|
| 342 |
-
configLabelKey = payload[key as keyof typeof payload] as string
|
| 343 |
-
} else if (
|
| 344 |
-
payloadPayload &&
|
| 345 |
-
key in payloadPayload &&
|
| 346 |
-
typeof payloadPayload[key as keyof typeof payloadPayload] === "string"
|
| 347 |
-
) {
|
| 348 |
-
configLabelKey = payloadPayload[
|
| 349 |
-
key as keyof typeof payloadPayload
|
| 350 |
-
] as string
|
| 351 |
-
}
|
| 352 |
-
|
| 353 |
-
return configLabelKey in config
|
| 354 |
-
? config[configLabelKey]
|
| 355 |
-
: config[key as keyof typeof config]
|
| 356 |
-
}
|
| 357 |
-
|
| 358 |
-
export {
|
| 359 |
-
ChartContainer,
|
| 360 |
-
ChartTooltip,
|
| 361 |
-
ChartTooltipContent,
|
| 362 |
-
ChartLegend,
|
| 363 |
-
ChartLegendContent,
|
| 364 |
-
ChartStyle,
|
| 365 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/checkbox.tsx
DELETED
|
@@ -1,28 +0,0 @@
|
|
| 1 |
-
import * as React from "react"
|
| 2 |
-
import * as CheckboxPrimitive from "@radix-ui/react-checkbox"
|
| 3 |
-
import { Check } from "lucide-react"
|
| 4 |
-
|
| 5 |
-
import { cn } from "@/lib/utils"
|
| 6 |
-
|
| 7 |
-
const Checkbox = React.forwardRef<
|
| 8 |
-
React.ElementRef<typeof CheckboxPrimitive.Root>,
|
| 9 |
-
React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>
|
| 10 |
-
>(({ className, ...props }, ref) => (
|
| 11 |
-
<CheckboxPrimitive.Root
|
| 12 |
-
ref={ref}
|
| 13 |
-
className={cn(
|
| 14 |
-
"grid place-content-center peer h-4 w-4 shrink-0 rounded-sm border border-primary shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
|
| 15 |
-
className
|
| 16 |
-
)}
|
| 17 |
-
{...props}
|
| 18 |
-
>
|
| 19 |
-
<CheckboxPrimitive.Indicator
|
| 20 |
-
className={cn("grid place-content-center text-current")}
|
| 21 |
-
>
|
| 22 |
-
<Check className="h-4 w-4" />
|
| 23 |
-
</CheckboxPrimitive.Indicator>
|
| 24 |
-
</CheckboxPrimitive.Root>
|
| 25 |
-
))
|
| 26 |
-
Checkbox.displayName = CheckboxPrimitive.Root.displayName
|
| 27 |
-
|
| 28 |
-
export { Checkbox }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/collapsible.tsx
DELETED
|
@@ -1,11 +0,0 @@
|
|
| 1 |
-
"use client"
|
| 2 |
-
|
| 3 |
-
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"
|
| 4 |
-
|
| 5 |
-
const Collapsible = CollapsiblePrimitive.Root
|
| 6 |
-
|
| 7 |
-
const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger
|
| 8 |
-
|
| 9 |
-
const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent
|
| 10 |
-
|
| 11 |
-
export { Collapsible, CollapsibleTrigger, CollapsibleContent }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/command.tsx
DELETED
|
@@ -1,153 +0,0 @@
|
|
| 1 |
-
"use client"
|
| 2 |
-
|
| 3 |
-
import * as React from "react"
|
| 4 |
-
import { type DialogProps } from "@radix-ui/react-dialog"
|
| 5 |
-
import { Command as CommandPrimitive } from "cmdk"
|
| 6 |
-
import { Search } from "lucide-react"
|
| 7 |
-
|
| 8 |
-
import { cn } from "@/lib/utils"
|
| 9 |
-
import { Dialog, DialogContent } from "@/components/ui/dialog"
|
| 10 |
-
|
| 11 |
-
const Command = React.forwardRef<
|
| 12 |
-
React.ElementRef<typeof CommandPrimitive>,
|
| 13 |
-
React.ComponentPropsWithoutRef<typeof CommandPrimitive>
|
| 14 |
-
>(({ className, ...props }, ref) => (
|
| 15 |
-
<CommandPrimitive
|
| 16 |
-
ref={ref}
|
| 17 |
-
className={cn(
|
| 18 |
-
"flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
|
| 19 |
-
className
|
| 20 |
-
)}
|
| 21 |
-
{...props}
|
| 22 |
-
/>
|
| 23 |
-
))
|
| 24 |
-
Command.displayName = CommandPrimitive.displayName
|
| 25 |
-
|
| 26 |
-
const CommandDialog = ({ children, ...props }: DialogProps) => {
|
| 27 |
-
return (
|
| 28 |
-
<Dialog {...props}>
|
| 29 |
-
<DialogContent className="overflow-hidden p-0">
|
| 30 |
-
<Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
|
| 31 |
-
{children}
|
| 32 |
-
</Command>
|
| 33 |
-
</DialogContent>
|
| 34 |
-
</Dialog>
|
| 35 |
-
)
|
| 36 |
-
}
|
| 37 |
-
|
| 38 |
-
const CommandInput = React.forwardRef<
|
| 39 |
-
React.ElementRef<typeof CommandPrimitive.Input>,
|
| 40 |
-
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
|
| 41 |
-
>(({ className, ...props }, ref) => (
|
| 42 |
-
<div className="flex items-center border-b px-3" cmdk-input-wrapper="">
|
| 43 |
-
<Search className="mr-2 h-4 w-4 shrink-0 opacity-50" />
|
| 44 |
-
<CommandPrimitive.Input
|
| 45 |
-
ref={ref}
|
| 46 |
-
className={cn(
|
| 47 |
-
"flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
|
| 48 |
-
className
|
| 49 |
-
)}
|
| 50 |
-
{...props}
|
| 51 |
-
/>
|
| 52 |
-
</div>
|
| 53 |
-
))
|
| 54 |
-
|
| 55 |
-
CommandInput.displayName = CommandPrimitive.Input.displayName
|
| 56 |
-
|
| 57 |
-
const CommandList = React.forwardRef<
|
| 58 |
-
React.ElementRef<typeof CommandPrimitive.List>,
|
| 59 |
-
React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
|
| 60 |
-
>(({ className, ...props }, ref) => (
|
| 61 |
-
<CommandPrimitive.List
|
| 62 |
-
ref={ref}
|
| 63 |
-
className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)}
|
| 64 |
-
{...props}
|
| 65 |
-
/>
|
| 66 |
-
))
|
| 67 |
-
|
| 68 |
-
CommandList.displayName = CommandPrimitive.List.displayName
|
| 69 |
-
|
| 70 |
-
const CommandEmpty = React.forwardRef<
|
| 71 |
-
React.ElementRef<typeof CommandPrimitive.Empty>,
|
| 72 |
-
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
|
| 73 |
-
>((props, ref) => (
|
| 74 |
-
<CommandPrimitive.Empty
|
| 75 |
-
ref={ref}
|
| 76 |
-
className="py-6 text-center text-sm"
|
| 77 |
-
{...props}
|
| 78 |
-
/>
|
| 79 |
-
))
|
| 80 |
-
|
| 81 |
-
CommandEmpty.displayName = CommandPrimitive.Empty.displayName
|
| 82 |
-
|
| 83 |
-
const CommandGroup = React.forwardRef<
|
| 84 |
-
React.ElementRef<typeof CommandPrimitive.Group>,
|
| 85 |
-
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>
|
| 86 |
-
>(({ className, ...props }, ref) => (
|
| 87 |
-
<CommandPrimitive.Group
|
| 88 |
-
ref={ref}
|
| 89 |
-
className={cn(
|
| 90 |
-
"overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
|
| 91 |
-
className
|
| 92 |
-
)}
|
| 93 |
-
{...props}
|
| 94 |
-
/>
|
| 95 |
-
))
|
| 96 |
-
|
| 97 |
-
CommandGroup.displayName = CommandPrimitive.Group.displayName
|
| 98 |
-
|
| 99 |
-
const CommandSeparator = React.forwardRef<
|
| 100 |
-
React.ElementRef<typeof CommandPrimitive.Separator>,
|
| 101 |
-
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>
|
| 102 |
-
>(({ className, ...props }, ref) => (
|
| 103 |
-
<CommandPrimitive.Separator
|
| 104 |
-
ref={ref}
|
| 105 |
-
className={cn("-mx-1 h-px bg-border", className)}
|
| 106 |
-
{...props}
|
| 107 |
-
/>
|
| 108 |
-
))
|
| 109 |
-
CommandSeparator.displayName = CommandPrimitive.Separator.displayName
|
| 110 |
-
|
| 111 |
-
const CommandItem = React.forwardRef<
|
| 112 |
-
React.ElementRef<typeof CommandPrimitive.Item>,
|
| 113 |
-
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
|
| 114 |
-
>(({ className, ...props }, ref) => (
|
| 115 |
-
<CommandPrimitive.Item
|
| 116 |
-
ref={ref}
|
| 117 |
-
className={cn(
|
| 118 |
-
"relative flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
| 119 |
-
className
|
| 120 |
-
)}
|
| 121 |
-
{...props}
|
| 122 |
-
/>
|
| 123 |
-
))
|
| 124 |
-
|
| 125 |
-
CommandItem.displayName = CommandPrimitive.Item.displayName
|
| 126 |
-
|
| 127 |
-
const CommandShortcut = ({
|
| 128 |
-
className,
|
| 129 |
-
...props
|
| 130 |
-
}: React.HTMLAttributes<HTMLSpanElement>) => {
|
| 131 |
-
return (
|
| 132 |
-
<span
|
| 133 |
-
className={cn(
|
| 134 |
-
"ml-auto text-xs tracking-widest text-muted-foreground",
|
| 135 |
-
className
|
| 136 |
-
)}
|
| 137 |
-
{...props}
|
| 138 |
-
/>
|
| 139 |
-
)
|
| 140 |
-
}
|
| 141 |
-
CommandShortcut.displayName = "CommandShortcut"
|
| 142 |
-
|
| 143 |
-
export {
|
| 144 |
-
Command,
|
| 145 |
-
CommandDialog,
|
| 146 |
-
CommandInput,
|
| 147 |
-
CommandList,
|
| 148 |
-
CommandEmpty,
|
| 149 |
-
CommandGroup,
|
| 150 |
-
CommandItem,
|
| 151 |
-
CommandShortcut,
|
| 152 |
-
CommandSeparator,
|
| 153 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/context-menu.tsx
DELETED
|
@@ -1,198 +0,0 @@
|
|
| 1 |
-
import * as React from "react"
|
| 2 |
-
import * as ContextMenuPrimitive from "@radix-ui/react-context-menu"
|
| 3 |
-
import { Check, ChevronRight, Circle } from "lucide-react"
|
| 4 |
-
|
| 5 |
-
import { cn } from "@/lib/utils"
|
| 6 |
-
|
| 7 |
-
const ContextMenu = ContextMenuPrimitive.Root
|
| 8 |
-
|
| 9 |
-
const ContextMenuTrigger = ContextMenuPrimitive.Trigger
|
| 10 |
-
|
| 11 |
-
const ContextMenuGroup = ContextMenuPrimitive.Group
|
| 12 |
-
|
| 13 |
-
const ContextMenuPortal = ContextMenuPrimitive.Portal
|
| 14 |
-
|
| 15 |
-
const ContextMenuSub = ContextMenuPrimitive.Sub
|
| 16 |
-
|
| 17 |
-
const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup
|
| 18 |
-
|
| 19 |
-
const ContextMenuSubTrigger = React.forwardRef<
|
| 20 |
-
React.ElementRef<typeof ContextMenuPrimitive.SubTrigger>,
|
| 21 |
-
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubTrigger> & {
|
| 22 |
-
inset?: boolean
|
| 23 |
-
}
|
| 24 |
-
>(({ className, inset, children, ...props }, ref) => (
|
| 25 |
-
<ContextMenuPrimitive.SubTrigger
|
| 26 |
-
ref={ref}
|
| 27 |
-
className={cn(
|
| 28 |
-
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
|
| 29 |
-
inset && "pl-8",
|
| 30 |
-
className
|
| 31 |
-
)}
|
| 32 |
-
{...props}
|
| 33 |
-
>
|
| 34 |
-
{children}
|
| 35 |
-
<ChevronRight className="ml-auto h-4 w-4" />
|
| 36 |
-
</ContextMenuPrimitive.SubTrigger>
|
| 37 |
-
))
|
| 38 |
-
ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName
|
| 39 |
-
|
| 40 |
-
const ContextMenuSubContent = React.forwardRef<
|
| 41 |
-
React.ElementRef<typeof ContextMenuPrimitive.SubContent>,
|
| 42 |
-
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubContent>
|
| 43 |
-
>(({ className, ...props }, ref) => (
|
| 44 |
-
<ContextMenuPrimitive.SubContent
|
| 45 |
-
ref={ref}
|
| 46 |
-
className={cn(
|
| 47 |
-
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg 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-context-menu-content-transform-origin]",
|
| 48 |
-
className
|
| 49 |
-
)}
|
| 50 |
-
{...props}
|
| 51 |
-
/>
|
| 52 |
-
))
|
| 53 |
-
ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName
|
| 54 |
-
|
| 55 |
-
const ContextMenuContent = React.forwardRef<
|
| 56 |
-
React.ElementRef<typeof ContextMenuPrimitive.Content>,
|
| 57 |
-
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Content>
|
| 58 |
-
>(({ className, ...props }, ref) => (
|
| 59 |
-
<ContextMenuPrimitive.Portal>
|
| 60 |
-
<ContextMenuPrimitive.Content
|
| 61 |
-
ref={ref}
|
| 62 |
-
className={cn(
|
| 63 |
-
"z-50 max-h-[--radix-context-menu-content-available-height] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md 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-context-menu-content-transform-origin]",
|
| 64 |
-
className
|
| 65 |
-
)}
|
| 66 |
-
{...props}
|
| 67 |
-
/>
|
| 68 |
-
</ContextMenuPrimitive.Portal>
|
| 69 |
-
))
|
| 70 |
-
ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName
|
| 71 |
-
|
| 72 |
-
const ContextMenuItem = React.forwardRef<
|
| 73 |
-
React.ElementRef<typeof ContextMenuPrimitive.Item>,
|
| 74 |
-
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Item> & {
|
| 75 |
-
inset?: boolean
|
| 76 |
-
}
|
| 77 |
-
>(({ className, inset, ...props }, ref) => (
|
| 78 |
-
<ContextMenuPrimitive.Item
|
| 79 |
-
ref={ref}
|
| 80 |
-
className={cn(
|
| 81 |
-
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
| 82 |
-
inset && "pl-8",
|
| 83 |
-
className
|
| 84 |
-
)}
|
| 85 |
-
{...props}
|
| 86 |
-
/>
|
| 87 |
-
))
|
| 88 |
-
ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName
|
| 89 |
-
|
| 90 |
-
const ContextMenuCheckboxItem = React.forwardRef<
|
| 91 |
-
React.ElementRef<typeof ContextMenuPrimitive.CheckboxItem>,
|
| 92 |
-
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.CheckboxItem>
|
| 93 |
-
>(({ className, children, checked, ...props }, ref) => (
|
| 94 |
-
<ContextMenuPrimitive.CheckboxItem
|
| 95 |
-
ref={ref}
|
| 96 |
-
className={cn(
|
| 97 |
-
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
| 98 |
-
className
|
| 99 |
-
)}
|
| 100 |
-
checked={checked}
|
| 101 |
-
{...props}
|
| 102 |
-
>
|
| 103 |
-
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
| 104 |
-
<ContextMenuPrimitive.ItemIndicator>
|
| 105 |
-
<Check className="h-4 w-4" />
|
| 106 |
-
</ContextMenuPrimitive.ItemIndicator>
|
| 107 |
-
</span>
|
| 108 |
-
{children}
|
| 109 |
-
</ContextMenuPrimitive.CheckboxItem>
|
| 110 |
-
))
|
| 111 |
-
ContextMenuCheckboxItem.displayName =
|
| 112 |
-
ContextMenuPrimitive.CheckboxItem.displayName
|
| 113 |
-
|
| 114 |
-
const ContextMenuRadioItem = React.forwardRef<
|
| 115 |
-
React.ElementRef<typeof ContextMenuPrimitive.RadioItem>,
|
| 116 |
-
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.RadioItem>
|
| 117 |
-
>(({ className, children, ...props }, ref) => (
|
| 118 |
-
<ContextMenuPrimitive.RadioItem
|
| 119 |
-
ref={ref}
|
| 120 |
-
className={cn(
|
| 121 |
-
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
| 122 |
-
className
|
| 123 |
-
)}
|
| 124 |
-
{...props}
|
| 125 |
-
>
|
| 126 |
-
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
| 127 |
-
<ContextMenuPrimitive.ItemIndicator>
|
| 128 |
-
<Circle className="h-4 w-4 fill-current" />
|
| 129 |
-
</ContextMenuPrimitive.ItemIndicator>
|
| 130 |
-
</span>
|
| 131 |
-
{children}
|
| 132 |
-
</ContextMenuPrimitive.RadioItem>
|
| 133 |
-
))
|
| 134 |
-
ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName
|
| 135 |
-
|
| 136 |
-
const ContextMenuLabel = React.forwardRef<
|
| 137 |
-
React.ElementRef<typeof ContextMenuPrimitive.Label>,
|
| 138 |
-
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Label> & {
|
| 139 |
-
inset?: boolean
|
| 140 |
-
}
|
| 141 |
-
>(({ className, inset, ...props }, ref) => (
|
| 142 |
-
<ContextMenuPrimitive.Label
|
| 143 |
-
ref={ref}
|
| 144 |
-
className={cn(
|
| 145 |
-
"px-2 py-1.5 text-sm font-semibold text-foreground",
|
| 146 |
-
inset && "pl-8",
|
| 147 |
-
className
|
| 148 |
-
)}
|
| 149 |
-
{...props}
|
| 150 |
-
/>
|
| 151 |
-
))
|
| 152 |
-
ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName
|
| 153 |
-
|
| 154 |
-
const ContextMenuSeparator = React.forwardRef<
|
| 155 |
-
React.ElementRef<typeof ContextMenuPrimitive.Separator>,
|
| 156 |
-
React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Separator>
|
| 157 |
-
>(({ className, ...props }, ref) => (
|
| 158 |
-
<ContextMenuPrimitive.Separator
|
| 159 |
-
ref={ref}
|
| 160 |
-
className={cn("-mx-1 my-1 h-px bg-border", className)}
|
| 161 |
-
{...props}
|
| 162 |
-
/>
|
| 163 |
-
))
|
| 164 |
-
ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName
|
| 165 |
-
|
| 166 |
-
const ContextMenuShortcut = ({
|
| 167 |
-
className,
|
| 168 |
-
...props
|
| 169 |
-
}: React.HTMLAttributes<HTMLSpanElement>) => {
|
| 170 |
-
return (
|
| 171 |
-
<span
|
| 172 |
-
className={cn(
|
| 173 |
-
"ml-auto text-xs tracking-widest text-muted-foreground",
|
| 174 |
-
className
|
| 175 |
-
)}
|
| 176 |
-
{...props}
|
| 177 |
-
/>
|
| 178 |
-
)
|
| 179 |
-
}
|
| 180 |
-
ContextMenuShortcut.displayName = "ContextMenuShortcut"
|
| 181 |
-
|
| 182 |
-
export {
|
| 183 |
-
ContextMenu,
|
| 184 |
-
ContextMenuTrigger,
|
| 185 |
-
ContextMenuContent,
|
| 186 |
-
ContextMenuItem,
|
| 187 |
-
ContextMenuCheckboxItem,
|
| 188 |
-
ContextMenuRadioItem,
|
| 189 |
-
ContextMenuLabel,
|
| 190 |
-
ContextMenuSeparator,
|
| 191 |
-
ContextMenuShortcut,
|
| 192 |
-
ContextMenuGroup,
|
| 193 |
-
ContextMenuPortal,
|
| 194 |
-
ContextMenuSub,
|
| 195 |
-
ContextMenuSubContent,
|
| 196 |
-
ContextMenuSubTrigger,
|
| 197 |
-
ContextMenuRadioGroup,
|
| 198 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/dialog.tsx
DELETED
|
@@ -1,120 +0,0 @@
|
|
| 1 |
-
import * as React from "react"
|
| 2 |
-
import * as DialogPrimitive from "@radix-ui/react-dialog"
|
| 3 |
-
import { X } from "lucide-react"
|
| 4 |
-
|
| 5 |
-
import { cn } from "@/lib/utils"
|
| 6 |
-
|
| 7 |
-
const Dialog = DialogPrimitive.Root
|
| 8 |
-
|
| 9 |
-
const DialogTrigger = DialogPrimitive.Trigger
|
| 10 |
-
|
| 11 |
-
const DialogPortal = DialogPrimitive.Portal
|
| 12 |
-
|
| 13 |
-
const DialogClose = DialogPrimitive.Close
|
| 14 |
-
|
| 15 |
-
const DialogOverlay = React.forwardRef<
|
| 16 |
-
React.ElementRef<typeof DialogPrimitive.Overlay>,
|
| 17 |
-
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
|
| 18 |
-
>(({ className, ...props }, ref) => (
|
| 19 |
-
<DialogPrimitive.Overlay
|
| 20 |
-
ref={ref}
|
| 21 |
-
className={cn(
|
| 22 |
-
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
| 23 |
-
className
|
| 24 |
-
)}
|
| 25 |
-
{...props}
|
| 26 |
-
/>
|
| 27 |
-
))
|
| 28 |
-
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
|
| 29 |
-
|
| 30 |
-
const DialogContent = React.forwardRef<
|
| 31 |
-
React.ElementRef<typeof DialogPrimitive.Content>,
|
| 32 |
-
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
|
| 33 |
-
>(({ className, children, ...props }, ref) => (
|
| 34 |
-
<DialogPortal>
|
| 35 |
-
<DialogOverlay />
|
| 36 |
-
<DialogPrimitive.Content
|
| 37 |
-
ref={ref}
|
| 38 |
-
className={cn(
|
| 39 |
-
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 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-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
|
| 40 |
-
className
|
| 41 |
-
)}
|
| 42 |
-
{...props}
|
| 43 |
-
>
|
| 44 |
-
{children}
|
| 45 |
-
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
|
| 46 |
-
<X className="h-4 w-4" />
|
| 47 |
-
<span className="sr-only">Close</span>
|
| 48 |
-
</DialogPrimitive.Close>
|
| 49 |
-
</DialogPrimitive.Content>
|
| 50 |
-
</DialogPortal>
|
| 51 |
-
))
|
| 52 |
-
DialogContent.displayName = DialogPrimitive.Content.displayName
|
| 53 |
-
|
| 54 |
-
const DialogHeader = ({
|
| 55 |
-
className,
|
| 56 |
-
...props
|
| 57 |
-
}: React.HTMLAttributes<HTMLDivElement>) => (
|
| 58 |
-
<div
|
| 59 |
-
className={cn(
|
| 60 |
-
"flex flex-col space-y-1.5 text-center sm:text-left",
|
| 61 |
-
className
|
| 62 |
-
)}
|
| 63 |
-
{...props}
|
| 64 |
-
/>
|
| 65 |
-
)
|
| 66 |
-
DialogHeader.displayName = "DialogHeader"
|
| 67 |
-
|
| 68 |
-
const DialogFooter = ({
|
| 69 |
-
className,
|
| 70 |
-
...props
|
| 71 |
-
}: React.HTMLAttributes<HTMLDivElement>) => (
|
| 72 |
-
<div
|
| 73 |
-
className={cn(
|
| 74 |
-
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
|
| 75 |
-
className
|
| 76 |
-
)}
|
| 77 |
-
{...props}
|
| 78 |
-
/>
|
| 79 |
-
)
|
| 80 |
-
DialogFooter.displayName = "DialogFooter"
|
| 81 |
-
|
| 82 |
-
const DialogTitle = React.forwardRef<
|
| 83 |
-
React.ElementRef<typeof DialogPrimitive.Title>,
|
| 84 |
-
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
|
| 85 |
-
>(({ className, ...props }, ref) => (
|
| 86 |
-
<DialogPrimitive.Title
|
| 87 |
-
ref={ref}
|
| 88 |
-
className={cn(
|
| 89 |
-
"text-lg font-semibold leading-none tracking-tight",
|
| 90 |
-
className
|
| 91 |
-
)}
|
| 92 |
-
{...props}
|
| 93 |
-
/>
|
| 94 |
-
))
|
| 95 |
-
DialogTitle.displayName = DialogPrimitive.Title.displayName
|
| 96 |
-
|
| 97 |
-
const DialogDescription = React.forwardRef<
|
| 98 |
-
React.ElementRef<typeof DialogPrimitive.Description>,
|
| 99 |
-
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
|
| 100 |
-
>(({ className, ...props }, ref) => (
|
| 101 |
-
<DialogPrimitive.Description
|
| 102 |
-
ref={ref}
|
| 103 |
-
className={cn("text-sm text-muted-foreground", className)}
|
| 104 |
-
{...props}
|
| 105 |
-
/>
|
| 106 |
-
))
|
| 107 |
-
DialogDescription.displayName = DialogPrimitive.Description.displayName
|
| 108 |
-
|
| 109 |
-
export {
|
| 110 |
-
Dialog,
|
| 111 |
-
DialogPortal,
|
| 112 |
-
DialogOverlay,
|
| 113 |
-
DialogTrigger,
|
| 114 |
-
DialogClose,
|
| 115 |
-
DialogContent,
|
| 116 |
-
DialogHeader,
|
| 117 |
-
DialogFooter,
|
| 118 |
-
DialogTitle,
|
| 119 |
-
DialogDescription,
|
| 120 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/drawer.tsx
DELETED
|
@@ -1,116 +0,0 @@
|
|
| 1 |
-
import * as React from "react"
|
| 2 |
-
import { Drawer as DrawerPrimitive } from "vaul"
|
| 3 |
-
|
| 4 |
-
import { cn } from "@/lib/utils"
|
| 5 |
-
|
| 6 |
-
const Drawer = ({
|
| 7 |
-
shouldScaleBackground = true,
|
| 8 |
-
...props
|
| 9 |
-
}: React.ComponentProps<typeof DrawerPrimitive.Root>) => (
|
| 10 |
-
<DrawerPrimitive.Root
|
| 11 |
-
shouldScaleBackground={shouldScaleBackground}
|
| 12 |
-
{...props}
|
| 13 |
-
/>
|
| 14 |
-
)
|
| 15 |
-
Drawer.displayName = "Drawer"
|
| 16 |
-
|
| 17 |
-
const DrawerTrigger = DrawerPrimitive.Trigger
|
| 18 |
-
|
| 19 |
-
const DrawerPortal = DrawerPrimitive.Portal
|
| 20 |
-
|
| 21 |
-
const DrawerClose = DrawerPrimitive.Close
|
| 22 |
-
|
| 23 |
-
const DrawerOverlay = React.forwardRef<
|
| 24 |
-
React.ElementRef<typeof DrawerPrimitive.Overlay>,
|
| 25 |
-
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Overlay>
|
| 26 |
-
>(({ className, ...props }, ref) => (
|
| 27 |
-
<DrawerPrimitive.Overlay
|
| 28 |
-
ref={ref}
|
| 29 |
-
className={cn("fixed inset-0 z-50 bg-black/80", className)}
|
| 30 |
-
{...props}
|
| 31 |
-
/>
|
| 32 |
-
))
|
| 33 |
-
DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName
|
| 34 |
-
|
| 35 |
-
const DrawerContent = React.forwardRef<
|
| 36 |
-
React.ElementRef<typeof DrawerPrimitive.Content>,
|
| 37 |
-
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Content>
|
| 38 |
-
>(({ className, children, ...props }, ref) => (
|
| 39 |
-
<DrawerPortal>
|
| 40 |
-
<DrawerOverlay />
|
| 41 |
-
<DrawerPrimitive.Content
|
| 42 |
-
ref={ref}
|
| 43 |
-
className={cn(
|
| 44 |
-
"fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border bg-background",
|
| 45 |
-
className
|
| 46 |
-
)}
|
| 47 |
-
{...props}
|
| 48 |
-
>
|
| 49 |
-
<div className="mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted" />
|
| 50 |
-
{children}
|
| 51 |
-
</DrawerPrimitive.Content>
|
| 52 |
-
</DrawerPortal>
|
| 53 |
-
))
|
| 54 |
-
DrawerContent.displayName = "DrawerContent"
|
| 55 |
-
|
| 56 |
-
const DrawerHeader = ({
|
| 57 |
-
className,
|
| 58 |
-
...props
|
| 59 |
-
}: React.HTMLAttributes<HTMLDivElement>) => (
|
| 60 |
-
<div
|
| 61 |
-
className={cn("grid gap-1.5 p-4 text-center sm:text-left", className)}
|
| 62 |
-
{...props}
|
| 63 |
-
/>
|
| 64 |
-
)
|
| 65 |
-
DrawerHeader.displayName = "DrawerHeader"
|
| 66 |
-
|
| 67 |
-
const DrawerFooter = ({
|
| 68 |
-
className,
|
| 69 |
-
...props
|
| 70 |
-
}: React.HTMLAttributes<HTMLDivElement>) => (
|
| 71 |
-
<div
|
| 72 |
-
className={cn("mt-auto flex flex-col gap-2 p-4", className)}
|
| 73 |
-
{...props}
|
| 74 |
-
/>
|
| 75 |
-
)
|
| 76 |
-
DrawerFooter.displayName = "DrawerFooter"
|
| 77 |
-
|
| 78 |
-
const DrawerTitle = React.forwardRef<
|
| 79 |
-
React.ElementRef<typeof DrawerPrimitive.Title>,
|
| 80 |
-
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Title>
|
| 81 |
-
>(({ className, ...props }, ref) => (
|
| 82 |
-
<DrawerPrimitive.Title
|
| 83 |
-
ref={ref}
|
| 84 |
-
className={cn(
|
| 85 |
-
"text-lg font-semibold leading-none tracking-tight",
|
| 86 |
-
className
|
| 87 |
-
)}
|
| 88 |
-
{...props}
|
| 89 |
-
/>
|
| 90 |
-
))
|
| 91 |
-
DrawerTitle.displayName = DrawerPrimitive.Title.displayName
|
| 92 |
-
|
| 93 |
-
const DrawerDescription = React.forwardRef<
|
| 94 |
-
React.ElementRef<typeof DrawerPrimitive.Description>,
|
| 95 |
-
React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Description>
|
| 96 |
-
>(({ className, ...props }, ref) => (
|
| 97 |
-
<DrawerPrimitive.Description
|
| 98 |
-
ref={ref}
|
| 99 |
-
className={cn("text-sm text-muted-foreground", className)}
|
| 100 |
-
{...props}
|
| 101 |
-
/>
|
| 102 |
-
))
|
| 103 |
-
DrawerDescription.displayName = DrawerPrimitive.Description.displayName
|
| 104 |
-
|
| 105 |
-
export {
|
| 106 |
-
Drawer,
|
| 107 |
-
DrawerPortal,
|
| 108 |
-
DrawerOverlay,
|
| 109 |
-
DrawerTrigger,
|
| 110 |
-
DrawerClose,
|
| 111 |
-
DrawerContent,
|
| 112 |
-
DrawerHeader,
|
| 113 |
-
DrawerFooter,
|
| 114 |
-
DrawerTitle,
|
| 115 |
-
DrawerDescription,
|
| 116 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/dropdown-menu.tsx
DELETED
|
@@ -1,201 +0,0 @@
|
|
| 1 |
-
"use client"
|
| 2 |
-
|
| 3 |
-
import * as React from "react"
|
| 4 |
-
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
|
| 5 |
-
import { Check, ChevronRight, Circle } from "lucide-react"
|
| 6 |
-
|
| 7 |
-
import { cn } from "@/lib/utils"
|
| 8 |
-
|
| 9 |
-
const DropdownMenu = DropdownMenuPrimitive.Root
|
| 10 |
-
|
| 11 |
-
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger
|
| 12 |
-
|
| 13 |
-
const DropdownMenuGroup = DropdownMenuPrimitive.Group
|
| 14 |
-
|
| 15 |
-
const DropdownMenuPortal = DropdownMenuPrimitive.Portal
|
| 16 |
-
|
| 17 |
-
const DropdownMenuSub = DropdownMenuPrimitive.Sub
|
| 18 |
-
|
| 19 |
-
const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup
|
| 20 |
-
|
| 21 |
-
const DropdownMenuSubTrigger = React.forwardRef<
|
| 22 |
-
React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,
|
| 23 |
-
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {
|
| 24 |
-
inset?: boolean
|
| 25 |
-
}
|
| 26 |
-
>(({ className, inset, children, ...props }, ref) => (
|
| 27 |
-
<DropdownMenuPrimitive.SubTrigger
|
| 28 |
-
ref={ref}
|
| 29 |
-
className={cn(
|
| 30 |
-
"flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
| 31 |
-
inset && "pl-8",
|
| 32 |
-
className
|
| 33 |
-
)}
|
| 34 |
-
{...props}
|
| 35 |
-
>
|
| 36 |
-
{children}
|
| 37 |
-
<ChevronRight className="ml-auto" />
|
| 38 |
-
</DropdownMenuPrimitive.SubTrigger>
|
| 39 |
-
))
|
| 40 |
-
DropdownMenuSubTrigger.displayName =
|
| 41 |
-
DropdownMenuPrimitive.SubTrigger.displayName
|
| 42 |
-
|
| 43 |
-
const DropdownMenuSubContent = React.forwardRef<
|
| 44 |
-
React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
|
| 45 |
-
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>
|
| 46 |
-
>(({ className, ...props }, ref) => (
|
| 47 |
-
<DropdownMenuPrimitive.SubContent
|
| 48 |
-
ref={ref}
|
| 49 |
-
className={cn(
|
| 50 |
-
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg 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-dropdown-menu-content-transform-origin]",
|
| 51 |
-
className
|
| 52 |
-
)}
|
| 53 |
-
{...props}
|
| 54 |
-
/>
|
| 55 |
-
))
|
| 56 |
-
DropdownMenuSubContent.displayName =
|
| 57 |
-
DropdownMenuPrimitive.SubContent.displayName
|
| 58 |
-
|
| 59 |
-
const DropdownMenuContent = React.forwardRef<
|
| 60 |
-
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
|
| 61 |
-
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
|
| 62 |
-
>(({ className, sideOffset = 4, ...props }, ref) => (
|
| 63 |
-
<DropdownMenuPrimitive.Portal>
|
| 64 |
-
<DropdownMenuPrimitive.Content
|
| 65 |
-
ref={ref}
|
| 66 |
-
sideOffset={sideOffset}
|
| 67 |
-
className={cn(
|
| 68 |
-
"z-50 max-h-[var(--radix-dropdown-menu-content-available-height)] min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md",
|
| 69 |
-
"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-dropdown-menu-content-transform-origin]",
|
| 70 |
-
className
|
| 71 |
-
)}
|
| 72 |
-
{...props}
|
| 73 |
-
/>
|
| 74 |
-
</DropdownMenuPrimitive.Portal>
|
| 75 |
-
))
|
| 76 |
-
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName
|
| 77 |
-
|
| 78 |
-
const DropdownMenuItem = React.forwardRef<
|
| 79 |
-
React.ElementRef<typeof DropdownMenuPrimitive.Item>,
|
| 80 |
-
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {
|
| 81 |
-
inset?: boolean
|
| 82 |
-
}
|
| 83 |
-
>(({ className, inset, ...props }, ref) => (
|
| 84 |
-
<DropdownMenuPrimitive.Item
|
| 85 |
-
ref={ref}
|
| 86 |
-
className={cn(
|
| 87 |
-
"relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0",
|
| 88 |
-
inset && "pl-8",
|
| 89 |
-
className
|
| 90 |
-
)}
|
| 91 |
-
{...props}
|
| 92 |
-
/>
|
| 93 |
-
))
|
| 94 |
-
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName
|
| 95 |
-
|
| 96 |
-
const DropdownMenuCheckboxItem = React.forwardRef<
|
| 97 |
-
React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,
|
| 98 |
-
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>
|
| 99 |
-
>(({ className, children, checked, ...props }, ref) => (
|
| 100 |
-
<DropdownMenuPrimitive.CheckboxItem
|
| 101 |
-
ref={ref}
|
| 102 |
-
className={cn(
|
| 103 |
-
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
| 104 |
-
className
|
| 105 |
-
)}
|
| 106 |
-
checked={checked}
|
| 107 |
-
{...props}
|
| 108 |
-
>
|
| 109 |
-
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
| 110 |
-
<DropdownMenuPrimitive.ItemIndicator>
|
| 111 |
-
<Check className="h-4 w-4" />
|
| 112 |
-
</DropdownMenuPrimitive.ItemIndicator>
|
| 113 |
-
</span>
|
| 114 |
-
{children}
|
| 115 |
-
</DropdownMenuPrimitive.CheckboxItem>
|
| 116 |
-
))
|
| 117 |
-
DropdownMenuCheckboxItem.displayName =
|
| 118 |
-
DropdownMenuPrimitive.CheckboxItem.displayName
|
| 119 |
-
|
| 120 |
-
const DropdownMenuRadioItem = React.forwardRef<
|
| 121 |
-
React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
|
| 122 |
-
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>
|
| 123 |
-
>(({ className, children, ...props }, ref) => (
|
| 124 |
-
<DropdownMenuPrimitive.RadioItem
|
| 125 |
-
ref={ref}
|
| 126 |
-
className={cn(
|
| 127 |
-
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
| 128 |
-
className
|
| 129 |
-
)}
|
| 130 |
-
{...props}
|
| 131 |
-
>
|
| 132 |
-
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
| 133 |
-
<DropdownMenuPrimitive.ItemIndicator>
|
| 134 |
-
<Circle className="h-2 w-2 fill-current" />
|
| 135 |
-
</DropdownMenuPrimitive.ItemIndicator>
|
| 136 |
-
</span>
|
| 137 |
-
{children}
|
| 138 |
-
</DropdownMenuPrimitive.RadioItem>
|
| 139 |
-
))
|
| 140 |
-
DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName
|
| 141 |
-
|
| 142 |
-
const DropdownMenuLabel = React.forwardRef<
|
| 143 |
-
React.ElementRef<typeof DropdownMenuPrimitive.Label>,
|
| 144 |
-
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {
|
| 145 |
-
inset?: boolean
|
| 146 |
-
}
|
| 147 |
-
>(({ className, inset, ...props }, ref) => (
|
| 148 |
-
<DropdownMenuPrimitive.Label
|
| 149 |
-
ref={ref}
|
| 150 |
-
className={cn(
|
| 151 |
-
"px-2 py-1.5 text-sm font-semibold",
|
| 152 |
-
inset && "pl-8",
|
| 153 |
-
className
|
| 154 |
-
)}
|
| 155 |
-
{...props}
|
| 156 |
-
/>
|
| 157 |
-
))
|
| 158 |
-
DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName
|
| 159 |
-
|
| 160 |
-
const DropdownMenuSeparator = React.forwardRef<
|
| 161 |
-
React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
|
| 162 |
-
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
|
| 163 |
-
>(({ className, ...props }, ref) => (
|
| 164 |
-
<DropdownMenuPrimitive.Separator
|
| 165 |
-
ref={ref}
|
| 166 |
-
className={cn("-mx-1 my-1 h-px bg-muted", className)}
|
| 167 |
-
{...props}
|
| 168 |
-
/>
|
| 169 |
-
))
|
| 170 |
-
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName
|
| 171 |
-
|
| 172 |
-
const DropdownMenuShortcut = ({
|
| 173 |
-
className,
|
| 174 |
-
...props
|
| 175 |
-
}: React.HTMLAttributes<HTMLSpanElement>) => {
|
| 176 |
-
return (
|
| 177 |
-
<span
|
| 178 |
-
className={cn("ml-auto text-xs tracking-widest opacity-60", className)}
|
| 179 |
-
{...props}
|
| 180 |
-
/>
|
| 181 |
-
)
|
| 182 |
-
}
|
| 183 |
-
DropdownMenuShortcut.displayName = "DropdownMenuShortcut"
|
| 184 |
-
|
| 185 |
-
export {
|
| 186 |
-
DropdownMenu,
|
| 187 |
-
DropdownMenuTrigger,
|
| 188 |
-
DropdownMenuContent,
|
| 189 |
-
DropdownMenuItem,
|
| 190 |
-
DropdownMenuCheckboxItem,
|
| 191 |
-
DropdownMenuRadioItem,
|
| 192 |
-
DropdownMenuLabel,
|
| 193 |
-
DropdownMenuSeparator,
|
| 194 |
-
DropdownMenuShortcut,
|
| 195 |
-
DropdownMenuGroup,
|
| 196 |
-
DropdownMenuPortal,
|
| 197 |
-
DropdownMenuSub,
|
| 198 |
-
DropdownMenuSubContent,
|
| 199 |
-
DropdownMenuSubTrigger,
|
| 200 |
-
DropdownMenuRadioGroup,
|
| 201 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/empty.tsx
DELETED
|
@@ -1,104 +0,0 @@
|
|
| 1 |
-
import { cva, type VariantProps } from "class-variance-authority"
|
| 2 |
-
|
| 3 |
-
import { cn } from "@/lib/utils"
|
| 4 |
-
|
| 5 |
-
function Empty({ className, ...props }: React.ComponentProps<"div">) {
|
| 6 |
-
return (
|
| 7 |
-
<div
|
| 8 |
-
data-slot="empty"
|
| 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 |
-
{...props}
|
| 14 |
-
/>
|
| 15 |
-
)
|
| 16 |
-
}
|
| 17 |
-
|
| 18 |
-
function EmptyHeader({ className, ...props }: React.ComponentProps<"div">) {
|
| 19 |
-
return (
|
| 20 |
-
<div
|
| 21 |
-
data-slot="empty-header"
|
| 22 |
-
className={cn(
|
| 23 |
-
"flex max-w-sm flex-col items-center gap-2 text-center",
|
| 24 |
-
className
|
| 25 |
-
)}
|
| 26 |
-
{...props}
|
| 27 |
-
/>
|
| 28 |
-
)
|
| 29 |
-
}
|
| 30 |
-
|
| 31 |
-
const emptyMediaVariants = cva(
|
| 32 |
-
"mb-2 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
| 33 |
-
{
|
| 34 |
-
variants: {
|
| 35 |
-
variant: {
|
| 36 |
-
default: "bg-transparent",
|
| 37 |
-
icon: "bg-muted text-foreground flex size-10 shrink-0 items-center justify-center rounded-lg [&_svg:not([class*='size-'])]:size-6",
|
| 38 |
-
},
|
| 39 |
-
},
|
| 40 |
-
defaultVariants: {
|
| 41 |
-
variant: "default",
|
| 42 |
-
},
|
| 43 |
-
}
|
| 44 |
-
)
|
| 45 |
-
|
| 46 |
-
function EmptyMedia({
|
| 47 |
-
className,
|
| 48 |
-
variant = "default",
|
| 49 |
-
...props
|
| 50 |
-
}: React.ComponentProps<"div"> & VariantProps<typeof emptyMediaVariants>) {
|
| 51 |
-
return (
|
| 52 |
-
<div
|
| 53 |
-
data-slot="empty-icon"
|
| 54 |
-
data-variant={variant}
|
| 55 |
-
className={cn(emptyMediaVariants({ variant, className }))}
|
| 56 |
-
{...props}
|
| 57 |
-
/>
|
| 58 |
-
)
|
| 59 |
-
}
|
| 60 |
-
|
| 61 |
-
function EmptyTitle({ className, ...props }: React.ComponentProps<"div">) {
|
| 62 |
-
return (
|
| 63 |
-
<div
|
| 64 |
-
data-slot="empty-title"
|
| 65 |
-
className={cn("text-lg font-medium tracking-tight", className)}
|
| 66 |
-
{...props}
|
| 67 |
-
/>
|
| 68 |
-
)
|
| 69 |
-
}
|
| 70 |
-
|
| 71 |
-
function EmptyDescription({ className, ...props }: React.ComponentProps<"p">) {
|
| 72 |
-
return (
|
| 73 |
-
<div
|
| 74 |
-
data-slot="empty-description"
|
| 75 |
-
className={cn(
|
| 76 |
-
"text-muted-foreground [&>a:hover]:text-primary text-sm/relaxed [&>a]:underline [&>a]:underline-offset-4",
|
| 77 |
-
className
|
| 78 |
-
)}
|
| 79 |
-
{...props}
|
| 80 |
-
/>
|
| 81 |
-
)
|
| 82 |
-
}
|
| 83 |
-
|
| 84 |
-
function EmptyContent({ className, ...props }: React.ComponentProps<"div">) {
|
| 85 |
-
return (
|
| 86 |
-
<div
|
| 87 |
-
data-slot="empty-content"
|
| 88 |
-
className={cn(
|
| 89 |
-
"flex w-full min-w-0 max-w-sm flex-col items-center gap-4 text-balance text-sm",
|
| 90 |
-
className
|
| 91 |
-
)}
|
| 92 |
-
{...props}
|
| 93 |
-
/>
|
| 94 |
-
)
|
| 95 |
-
}
|
| 96 |
-
|
| 97 |
-
export {
|
| 98 |
-
Empty,
|
| 99 |
-
EmptyHeader,
|
| 100 |
-
EmptyTitle,
|
| 101 |
-
EmptyDescription,
|
| 102 |
-
EmptyContent,
|
| 103 |
-
EmptyMedia,
|
| 104 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/field.tsx
DELETED
|
@@ -1,244 +0,0 @@
|
|
| 1 |
-
"use client"
|
| 2 |
-
|
| 3 |
-
import { useMemo } from "react"
|
| 4 |
-
import { cva, type VariantProps } from "class-variance-authority"
|
| 5 |
-
|
| 6 |
-
import { cn } from "@/lib/utils"
|
| 7 |
-
import { Label } from "@/components/ui/label"
|
| 8 |
-
import { Separator } from "@/components/ui/separator"
|
| 9 |
-
|
| 10 |
-
function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) {
|
| 11 |
-
return (
|
| 12 |
-
<fieldset
|
| 13 |
-
data-slot="field-set"
|
| 14 |
-
className={cn(
|
| 15 |
-
"flex flex-col gap-6",
|
| 16 |
-
"has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3",
|
| 17 |
-
className
|
| 18 |
-
)}
|
| 19 |
-
{...props}
|
| 20 |
-
/>
|
| 21 |
-
)
|
| 22 |
-
}
|
| 23 |
-
|
| 24 |
-
function FieldLegend({
|
| 25 |
-
className,
|
| 26 |
-
variant = "legend",
|
| 27 |
-
...props
|
| 28 |
-
}: React.ComponentProps<"legend"> & { variant?: "legend" | "label" }) {
|
| 29 |
-
return (
|
| 30 |
-
<legend
|
| 31 |
-
data-slot="field-legend"
|
| 32 |
-
data-variant={variant}
|
| 33 |
-
className={cn(
|
| 34 |
-
"mb-3 font-medium",
|
| 35 |
-
"data-[variant=legend]:text-base",
|
| 36 |
-
"data-[variant=label]:text-sm",
|
| 37 |
-
className
|
| 38 |
-
)}
|
| 39 |
-
{...props}
|
| 40 |
-
/>
|
| 41 |
-
)
|
| 42 |
-
}
|
| 43 |
-
|
| 44 |
-
function FieldGroup({ className, ...props }: React.ComponentProps<"div">) {
|
| 45 |
-
return (
|
| 46 |
-
<div
|
| 47 |
-
data-slot="field-group"
|
| 48 |
-
className={cn(
|
| 49 |
-
"group/field-group @container/field-group flex w-full flex-col gap-7 data-[slot=checkbox-group]:gap-3 [&>[data-slot=field-group]]:gap-4",
|
| 50 |
-
className
|
| 51 |
-
)}
|
| 52 |
-
{...props}
|
| 53 |
-
/>
|
| 54 |
-
)
|
| 55 |
-
}
|
| 56 |
-
|
| 57 |
-
const fieldVariants = cva(
|
| 58 |
-
"group/field data-[invalid=true]:text-destructive flex w-full gap-3",
|
| 59 |
-
{
|
| 60 |
-
variants: {
|
| 61 |
-
orientation: {
|
| 62 |
-
vertical: ["flex-col [&>*]:w-full [&>.sr-only]:w-auto"],
|
| 63 |
-
horizontal: [
|
| 64 |
-
"flex-row items-center",
|
| 65 |
-
"[&>[data-slot=field-label]]:flex-auto",
|
| 66 |
-
"has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px has-[>[data-slot=field-content]]:items-start",
|
| 67 |
-
],
|
| 68 |
-
responsive: [
|
| 69 |
-
"@md/field-group:flex-row @md/field-group:items-center @md/field-group:[&>*]:w-auto flex-col [&>*]:w-full [&>.sr-only]:w-auto",
|
| 70 |
-
"@md/field-group:[&>[data-slot=field-label]]:flex-auto",
|
| 71 |
-
"@md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
|
| 72 |
-
],
|
| 73 |
-
},
|
| 74 |
-
},
|
| 75 |
-
defaultVariants: {
|
| 76 |
-
orientation: "vertical",
|
| 77 |
-
},
|
| 78 |
-
}
|
| 79 |
-
)
|
| 80 |
-
|
| 81 |
-
function Field({
|
| 82 |
-
className,
|
| 83 |
-
orientation = "vertical",
|
| 84 |
-
...props
|
| 85 |
-
}: React.ComponentProps<"div"> & VariantProps<typeof fieldVariants>) {
|
| 86 |
-
return (
|
| 87 |
-
<div
|
| 88 |
-
role="group"
|
| 89 |
-
data-slot="field"
|
| 90 |
-
data-orientation={orientation}
|
| 91 |
-
className={cn(fieldVariants({ orientation }), className)}
|
| 92 |
-
{...props}
|
| 93 |
-
/>
|
| 94 |
-
)
|
| 95 |
-
}
|
| 96 |
-
|
| 97 |
-
function FieldContent({ className, ...props }: React.ComponentProps<"div">) {
|
| 98 |
-
return (
|
| 99 |
-
<div
|
| 100 |
-
data-slot="field-content"
|
| 101 |
-
className={cn(
|
| 102 |
-
"group/field-content flex flex-1 flex-col gap-1.5 leading-snug",
|
| 103 |
-
className
|
| 104 |
-
)}
|
| 105 |
-
{...props}
|
| 106 |
-
/>
|
| 107 |
-
)
|
| 108 |
-
}
|
| 109 |
-
|
| 110 |
-
function FieldLabel({
|
| 111 |
-
className,
|
| 112 |
-
...props
|
| 113 |
-
}: React.ComponentProps<typeof Label>) {
|
| 114 |
-
return (
|
| 115 |
-
<Label
|
| 116 |
-
data-slot="field-label"
|
| 117 |
-
className={cn(
|
| 118 |
-
"group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50",
|
| 119 |
-
"has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border [&>[data-slot=field]]:p-4",
|
| 120 |
-
"has-data-[state=checked]:bg-primary/5 has-data-[state=checked]:border-primary dark:has-data-[state=checked]:bg-primary/10",
|
| 121 |
-
className
|
| 122 |
-
)}
|
| 123 |
-
{...props}
|
| 124 |
-
/>
|
| 125 |
-
)
|
| 126 |
-
}
|
| 127 |
-
|
| 128 |
-
function FieldTitle({ className, ...props }: React.ComponentProps<"div">) {
|
| 129 |
-
return (
|
| 130 |
-
<div
|
| 131 |
-
data-slot="field-label"
|
| 132 |
-
className={cn(
|
| 133 |
-
"flex w-fit items-center gap-2 text-sm font-medium leading-snug group-data-[disabled=true]/field:opacity-50",
|
| 134 |
-
className
|
| 135 |
-
)}
|
| 136 |
-
{...props}
|
| 137 |
-
/>
|
| 138 |
-
)
|
| 139 |
-
}
|
| 140 |
-
|
| 141 |
-
function FieldDescription({ className, ...props }: React.ComponentProps<"p">) {
|
| 142 |
-
return (
|
| 143 |
-
<p
|
| 144 |
-
data-slot="field-description"
|
| 145 |
-
className={cn(
|
| 146 |
-
"text-muted-foreground text-sm font-normal leading-normal group-has-[[data-orientation=horizontal]]/field:text-balance",
|
| 147 |
-
"nth-last-2:-mt-1 last:mt-0 [[data-variant=legend]+&]:-mt-1.5",
|
| 148 |
-
"[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4",
|
| 149 |
-
className
|
| 150 |
-
)}
|
| 151 |
-
{...props}
|
| 152 |
-
/>
|
| 153 |
-
)
|
| 154 |
-
}
|
| 155 |
-
|
| 156 |
-
function FieldSeparator({
|
| 157 |
-
children,
|
| 158 |
-
className,
|
| 159 |
-
...props
|
| 160 |
-
}: React.ComponentProps<"div"> & {
|
| 161 |
-
children?: React.ReactNode
|
| 162 |
-
}) {
|
| 163 |
-
return (
|
| 164 |
-
<div
|
| 165 |
-
data-slot="field-separator"
|
| 166 |
-
data-content={!!children}
|
| 167 |
-
className={cn(
|
| 168 |
-
"relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2",
|
| 169 |
-
className
|
| 170 |
-
)}
|
| 171 |
-
{...props}
|
| 172 |
-
>
|
| 173 |
-
<Separator className="absolute inset-0 top-1/2" />
|
| 174 |
-
{children && (
|
| 175 |
-
<span
|
| 176 |
-
className="bg-background text-muted-foreground relative mx-auto block w-fit px-2"
|
| 177 |
-
data-slot="field-separator-content"
|
| 178 |
-
>
|
| 179 |
-
{children}
|
| 180 |
-
</span>
|
| 181 |
-
)}
|
| 182 |
-
</div>
|
| 183 |
-
)
|
| 184 |
-
}
|
| 185 |
-
|
| 186 |
-
function FieldError({
|
| 187 |
-
className,
|
| 188 |
-
children,
|
| 189 |
-
errors,
|
| 190 |
-
...props
|
| 191 |
-
}: React.ComponentProps<"div"> & {
|
| 192 |
-
errors?: Array<{ message?: string } | undefined>
|
| 193 |
-
}) {
|
| 194 |
-
const content = useMemo(() => {
|
| 195 |
-
if (children) {
|
| 196 |
-
return children
|
| 197 |
-
}
|
| 198 |
-
|
| 199 |
-
if (!errors) {
|
| 200 |
-
return null
|
| 201 |
-
}
|
| 202 |
-
|
| 203 |
-
if (errors?.length === 1 && errors[0]?.message) {
|
| 204 |
-
return errors[0].message
|
| 205 |
-
}
|
| 206 |
-
|
| 207 |
-
return (
|
| 208 |
-
<ul className="ml-4 flex list-disc flex-col gap-1">
|
| 209 |
-
{errors.map(
|
| 210 |
-
(error, index) =>
|
| 211 |
-
error?.message && <li key={index}>{error.message}</li>
|
| 212 |
-
)}
|
| 213 |
-
</ul>
|
| 214 |
-
)
|
| 215 |
-
}, [children, errors])
|
| 216 |
-
|
| 217 |
-
if (!content) {
|
| 218 |
-
return null
|
| 219 |
-
}
|
| 220 |
-
|
| 221 |
-
return (
|
| 222 |
-
<div
|
| 223 |
-
role="alert"
|
| 224 |
-
data-slot="field-error"
|
| 225 |
-
className={cn("text-destructive text-sm font-normal", className)}
|
| 226 |
-
{...props}
|
| 227 |
-
>
|
| 228 |
-
{content}
|
| 229 |
-
</div>
|
| 230 |
-
)
|
| 231 |
-
}
|
| 232 |
-
|
| 233 |
-
export {
|
| 234 |
-
Field,
|
| 235 |
-
FieldLabel,
|
| 236 |
-
FieldDescription,
|
| 237 |
-
FieldError,
|
| 238 |
-
FieldGroup,
|
| 239 |
-
FieldLegend,
|
| 240 |
-
FieldSeparator,
|
| 241 |
-
FieldSet,
|
| 242 |
-
FieldContent,
|
| 243 |
-
FieldTitle,
|
| 244 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/form.tsx
DELETED
|
@@ -1,176 +0,0 @@
|
|
| 1 |
-
import * as React from "react"
|
| 2 |
-
import * as LabelPrimitive from "@radix-ui/react-label"
|
| 3 |
-
import { Slot } from "@radix-ui/react-slot"
|
| 4 |
-
import {
|
| 5 |
-
Controller,
|
| 6 |
-
FormProvider,
|
| 7 |
-
useFormContext,
|
| 8 |
-
type ControllerProps,
|
| 9 |
-
type FieldPath,
|
| 10 |
-
type FieldValues,
|
| 11 |
-
} from "react-hook-form"
|
| 12 |
-
|
| 13 |
-
import { cn } from "@/lib/utils"
|
| 14 |
-
import { Label } from "@/components/ui/label"
|
| 15 |
-
|
| 16 |
-
const Form = FormProvider
|
| 17 |
-
|
| 18 |
-
type FormFieldContextValue<
|
| 19 |
-
TFieldValues extends FieldValues = FieldValues,
|
| 20 |
-
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
|
| 21 |
-
> = {
|
| 22 |
-
name: TName
|
| 23 |
-
}
|
| 24 |
-
|
| 25 |
-
const FormFieldContext = React.createContext<FormFieldContextValue | null>(null)
|
| 26 |
-
|
| 27 |
-
const FormField = <
|
| 28 |
-
TFieldValues extends FieldValues = FieldValues,
|
| 29 |
-
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
|
| 30 |
-
>({
|
| 31 |
-
...props
|
| 32 |
-
}: ControllerProps<TFieldValues, TName>) => {
|
| 33 |
-
return (
|
| 34 |
-
<FormFieldContext.Provider value={{ name: props.name }}>
|
| 35 |
-
<Controller {...props} />
|
| 36 |
-
</FormFieldContext.Provider>
|
| 37 |
-
)
|
| 38 |
-
}
|
| 39 |
-
|
| 40 |
-
const useFormField = () => {
|
| 41 |
-
const fieldContext = React.useContext(FormFieldContext)
|
| 42 |
-
const itemContext = React.useContext(FormItemContext)
|
| 43 |
-
const { getFieldState, formState } = useFormContext()
|
| 44 |
-
|
| 45 |
-
if (!fieldContext) {
|
| 46 |
-
throw new Error("useFormField should be used within <FormField>")
|
| 47 |
-
}
|
| 48 |
-
|
| 49 |
-
if (!itemContext) {
|
| 50 |
-
throw new Error("useFormField should be used within <FormItem>")
|
| 51 |
-
}
|
| 52 |
-
|
| 53 |
-
const fieldState = getFieldState(fieldContext.name, formState)
|
| 54 |
-
|
| 55 |
-
const { id } = itemContext
|
| 56 |
-
|
| 57 |
-
return {
|
| 58 |
-
id,
|
| 59 |
-
name: fieldContext.name,
|
| 60 |
-
formItemId: `${id}-form-item`,
|
| 61 |
-
formDescriptionId: `${id}-form-item-description`,
|
| 62 |
-
formMessageId: `${id}-form-item-message`,
|
| 63 |
-
...fieldState,
|
| 64 |
-
}
|
| 65 |
-
}
|
| 66 |
-
|
| 67 |
-
type FormItemContextValue = {
|
| 68 |
-
id: string
|
| 69 |
-
}
|
| 70 |
-
|
| 71 |
-
const FormItemContext = React.createContext<FormItemContextValue | null>(null)
|
| 72 |
-
|
| 73 |
-
const FormItem = React.forwardRef<
|
| 74 |
-
HTMLDivElement,
|
| 75 |
-
React.HTMLAttributes<HTMLDivElement>
|
| 76 |
-
>(({ className, ...props }, ref) => {
|
| 77 |
-
const id = React.useId()
|
| 78 |
-
|
| 79 |
-
return (
|
| 80 |
-
<FormItemContext.Provider value={{ id }}>
|
| 81 |
-
<div ref={ref} className={cn("space-y-2", className)} {...props} />
|
| 82 |
-
</FormItemContext.Provider>
|
| 83 |
-
)
|
| 84 |
-
})
|
| 85 |
-
FormItem.displayName = "FormItem"
|
| 86 |
-
|
| 87 |
-
const FormLabel = React.forwardRef<
|
| 88 |
-
React.ElementRef<typeof LabelPrimitive.Root>,
|
| 89 |
-
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>
|
| 90 |
-
>(({ className, ...props }, ref) => {
|
| 91 |
-
const { error, formItemId } = useFormField()
|
| 92 |
-
|
| 93 |
-
return (
|
| 94 |
-
<Label
|
| 95 |
-
ref={ref}
|
| 96 |
-
className={cn(error && "text-destructive", className)}
|
| 97 |
-
htmlFor={formItemId}
|
| 98 |
-
{...props}
|
| 99 |
-
/>
|
| 100 |
-
)
|
| 101 |
-
})
|
| 102 |
-
FormLabel.displayName = "FormLabel"
|
| 103 |
-
|
| 104 |
-
const FormControl = React.forwardRef<
|
| 105 |
-
React.ElementRef<typeof Slot>,
|
| 106 |
-
React.ComponentPropsWithoutRef<typeof Slot>
|
| 107 |
-
>(({ ...props }, ref) => {
|
| 108 |
-
const { error, formItemId, formDescriptionId, formMessageId } = useFormField()
|
| 109 |
-
|
| 110 |
-
return (
|
| 111 |
-
<Slot
|
| 112 |
-
ref={ref}
|
| 113 |
-
id={formItemId}
|
| 114 |
-
aria-describedby={
|
| 115 |
-
!error
|
| 116 |
-
? `${formDescriptionId}`
|
| 117 |
-
: `${formDescriptionId} ${formMessageId}`
|
| 118 |
-
}
|
| 119 |
-
aria-invalid={!!error}
|
| 120 |
-
{...props}
|
| 121 |
-
/>
|
| 122 |
-
)
|
| 123 |
-
})
|
| 124 |
-
FormControl.displayName = "FormControl"
|
| 125 |
-
|
| 126 |
-
const FormDescription = React.forwardRef<
|
| 127 |
-
HTMLParagraphElement,
|
| 128 |
-
React.HTMLAttributes<HTMLParagraphElement>
|
| 129 |
-
>(({ className, ...props }, ref) => {
|
| 130 |
-
const { formDescriptionId } = useFormField()
|
| 131 |
-
|
| 132 |
-
return (
|
| 133 |
-
<p
|
| 134 |
-
ref={ref}
|
| 135 |
-
id={formDescriptionId}
|
| 136 |
-
className={cn("text-[0.8rem] text-muted-foreground", className)}
|
| 137 |
-
{...props}
|
| 138 |
-
/>
|
| 139 |
-
)
|
| 140 |
-
})
|
| 141 |
-
FormDescription.displayName = "FormDescription"
|
| 142 |
-
|
| 143 |
-
const FormMessage = React.forwardRef<
|
| 144 |
-
HTMLParagraphElement,
|
| 145 |
-
React.HTMLAttributes<HTMLParagraphElement>
|
| 146 |
-
>(({ className, children, ...props }, ref) => {
|
| 147 |
-
const { error, formMessageId } = useFormField()
|
| 148 |
-
const body = error ? String(error?.message ?? "") : children
|
| 149 |
-
|
| 150 |
-
if (!body) {
|
| 151 |
-
return null
|
| 152 |
-
}
|
| 153 |
-
|
| 154 |
-
return (
|
| 155 |
-
<p
|
| 156 |
-
ref={ref}
|
| 157 |
-
id={formMessageId}
|
| 158 |
-
className={cn("text-[0.8rem] font-medium text-destructive", className)}
|
| 159 |
-
{...props}
|
| 160 |
-
>
|
| 161 |
-
{body}
|
| 162 |
-
</p>
|
| 163 |
-
)
|
| 164 |
-
})
|
| 165 |
-
FormMessage.displayName = "FormMessage"
|
| 166 |
-
|
| 167 |
-
export {
|
| 168 |
-
useFormField,
|
| 169 |
-
Form,
|
| 170 |
-
FormItem,
|
| 171 |
-
FormLabel,
|
| 172 |
-
FormControl,
|
| 173 |
-
FormDescription,
|
| 174 |
-
FormMessage,
|
| 175 |
-
FormField,
|
| 176 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/hover-card.tsx
DELETED
|
@@ -1,27 +0,0 @@
|
|
| 1 |
-
import * as React from "react"
|
| 2 |
-
import * as HoverCardPrimitive from "@radix-ui/react-hover-card"
|
| 3 |
-
|
| 4 |
-
import { cn } from "@/lib/utils"
|
| 5 |
-
|
| 6 |
-
const HoverCard = HoverCardPrimitive.Root
|
| 7 |
-
|
| 8 |
-
const HoverCardTrigger = HoverCardPrimitive.Trigger
|
| 9 |
-
|
| 10 |
-
const HoverCardContent = React.forwardRef<
|
| 11 |
-
React.ElementRef<typeof HoverCardPrimitive.Content>,
|
| 12 |
-
React.ComponentPropsWithoutRef<typeof HoverCardPrimitive.Content>
|
| 13 |
-
>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
|
| 14 |
-
<HoverCardPrimitive.Content
|
| 15 |
-
ref={ref}
|
| 16 |
-
align={align}
|
| 17 |
-
sideOffset={sideOffset}
|
| 18 |
-
className={cn(
|
| 19 |
-
"z-50 w-64 rounded-md border bg-popover p-4 text-popover-foreground 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-hover-card-content-transform-origin]",
|
| 20 |
-
className
|
| 21 |
-
)}
|
| 22 |
-
{...props}
|
| 23 |
-
/>
|
| 24 |
-
))
|
| 25 |
-
HoverCardContent.displayName = HoverCardPrimitive.Content.displayName
|
| 26 |
-
|
| 27 |
-
export { HoverCard, HoverCardTrigger, HoverCardContent }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/input-group.tsx
DELETED
|
@@ -1,165 +0,0 @@
|
|
| 1 |
-
import * as React from "react"
|
| 2 |
-
import { cva, type VariantProps } from "class-variance-authority"
|
| 3 |
-
|
| 4 |
-
import { cn } from "@/lib/utils"
|
| 5 |
-
import { Button } from "@/components/ui/button"
|
| 6 |
-
import { Input } from "@/components/ui/input"
|
| 7 |
-
import { Textarea } from "@/components/ui/textarea"
|
| 8 |
-
|
| 9 |
-
function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
|
| 10 |
-
return (
|
| 11 |
-
<div
|
| 12 |
-
data-slot="input-group"
|
| 13 |
-
role="group"
|
| 14 |
-
className={cn(
|
| 15 |
-
"group/input-group border-input dark:bg-input/30 shadow-xs relative flex w-full items-center rounded-md border outline-none transition-[color,box-shadow]",
|
| 16 |
-
"h-9 has-[>textarea]:h-auto",
|
| 17 |
-
|
| 18 |
-
"has-[>[data-align=inline-start]]:[&>input]:pl-2",
|
| 19 |
-
"has-[>[data-align=inline-end]]:[&>input]:pr-2",
|
| 20 |
-
"has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3",
|
| 21 |
-
"has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3",
|
| 22 |
-
|
| 23 |
-
"has-[[data-slot=input-group-control]:focus-visible]:ring-ring has-[[data-slot=input-group-control]:focus-visible]:ring-1",
|
| 24 |
-
|
| 25 |
-
"has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40",
|
| 26 |
-
|
| 27 |
-
className
|
| 28 |
-
)}
|
| 29 |
-
{...props}
|
| 30 |
-
/>
|
| 31 |
-
)
|
| 32 |
-
}
|
| 33 |
-
|
| 34 |
-
const inputGroupAddonVariants = cva(
|
| 35 |
-
"text-muted-foreground flex h-auto cursor-text select-none items-center justify-center gap-2 py-1.5 text-sm font-medium group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4",
|
| 36 |
-
{
|
| 37 |
-
variants: {
|
| 38 |
-
align: {
|
| 39 |
-
"inline-start":
|
| 40 |
-
"order-first pl-3 has-[>button]:ml-[-0.45rem] has-[>kbd]:ml-[-0.35rem]",
|
| 41 |
-
"inline-end":
|
| 42 |
-
"order-last pr-3 has-[>button]:mr-[-0.4rem] has-[>kbd]:mr-[-0.35rem]",
|
| 43 |
-
"block-start":
|
| 44 |
-
"[.border-b]:pb-3 order-first w-full justify-start px-3 pt-3 group-has-[>input]/input-group:pt-2.5",
|
| 45 |
-
"block-end":
|
| 46 |
-
"[.border-t]:pt-3 order-last w-full justify-start px-3 pb-3 group-has-[>input]/input-group:pb-2.5",
|
| 47 |
-
},
|
| 48 |
-
},
|
| 49 |
-
defaultVariants: {
|
| 50 |
-
align: "inline-start",
|
| 51 |
-
},
|
| 52 |
-
}
|
| 53 |
-
)
|
| 54 |
-
|
| 55 |
-
function InputGroupAddon({
|
| 56 |
-
className,
|
| 57 |
-
align = "inline-start",
|
| 58 |
-
...props
|
| 59 |
-
}: React.ComponentProps<"div"> & VariantProps<typeof inputGroupAddonVariants>) {
|
| 60 |
-
return (
|
| 61 |
-
<div
|
| 62 |
-
role="group"
|
| 63 |
-
data-slot="input-group-addon"
|
| 64 |
-
data-align={align}
|
| 65 |
-
className={cn(inputGroupAddonVariants({ align }), className)}
|
| 66 |
-
onClick={(e) => {
|
| 67 |
-
if ((e.target as HTMLElement).closest("button")) {
|
| 68 |
-
return
|
| 69 |
-
}
|
| 70 |
-
e.currentTarget.parentElement?.querySelector("input")?.focus()
|
| 71 |
-
}}
|
| 72 |
-
{...props}
|
| 73 |
-
/>
|
| 74 |
-
)
|
| 75 |
-
}
|
| 76 |
-
|
| 77 |
-
const inputGroupButtonVariants = cva(
|
| 78 |
-
"flex items-center gap-2 text-sm shadow-none",
|
| 79 |
-
{
|
| 80 |
-
variants: {
|
| 81 |
-
size: {
|
| 82 |
-
xs: "h-6 gap-1 rounded-[calc(var(--radius)-5px)] px-2 has-[>svg]:px-2 [&>svg:not([class*='size-'])]:size-3.5",
|
| 83 |
-
sm: "h-8 gap-1.5 rounded-md px-2.5 has-[>svg]:px-2.5",
|
| 84 |
-
"icon-xs":
|
| 85 |
-
"size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0",
|
| 86 |
-
"icon-sm": "size-8 p-0 has-[>svg]:p-0",
|
| 87 |
-
},
|
| 88 |
-
},
|
| 89 |
-
defaultVariants: {
|
| 90 |
-
size: "xs",
|
| 91 |
-
},
|
| 92 |
-
}
|
| 93 |
-
)
|
| 94 |
-
|
| 95 |
-
function InputGroupButton({
|
| 96 |
-
className,
|
| 97 |
-
type = "button",
|
| 98 |
-
variant = "ghost",
|
| 99 |
-
size = "xs",
|
| 100 |
-
...props
|
| 101 |
-
}: Omit<React.ComponentProps<typeof Button>, "size"> &
|
| 102 |
-
VariantProps<typeof inputGroupButtonVariants>) {
|
| 103 |
-
return (
|
| 104 |
-
<Button
|
| 105 |
-
type={type}
|
| 106 |
-
data-size={size}
|
| 107 |
-
variant={variant}
|
| 108 |
-
className={cn(inputGroupButtonVariants({ size }), className)}
|
| 109 |
-
{...props}
|
| 110 |
-
/>
|
| 111 |
-
)
|
| 112 |
-
}
|
| 113 |
-
|
| 114 |
-
function InputGroupText({ className, ...props }: React.ComponentProps<"span">) {
|
| 115 |
-
return (
|
| 116 |
-
<span
|
| 117 |
-
className={cn(
|
| 118 |
-
"text-muted-foreground flex items-center gap-2 text-sm [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none",
|
| 119 |
-
className
|
| 120 |
-
)}
|
| 121 |
-
{...props}
|
| 122 |
-
/>
|
| 123 |
-
)
|
| 124 |
-
}
|
| 125 |
-
|
| 126 |
-
function InputGroupInput({
|
| 127 |
-
className,
|
| 128 |
-
...props
|
| 129 |
-
}: React.ComponentProps<"input">) {
|
| 130 |
-
return (
|
| 131 |
-
<Input
|
| 132 |
-
data-slot="input-group-control"
|
| 133 |
-
className={cn(
|
| 134 |
-
"flex-1 rounded-none border-0 bg-transparent shadow-none focus-visible:ring-0 dark:bg-transparent",
|
| 135 |
-
className
|
| 136 |
-
)}
|
| 137 |
-
{...props}
|
| 138 |
-
/>
|
| 139 |
-
)
|
| 140 |
-
}
|
| 141 |
-
|
| 142 |
-
function InputGroupTextarea({
|
| 143 |
-
className,
|
| 144 |
-
...props
|
| 145 |
-
}: React.ComponentProps<"textarea">) {
|
| 146 |
-
return (
|
| 147 |
-
<Textarea
|
| 148 |
-
data-slot="input-group-control"
|
| 149 |
-
className={cn(
|
| 150 |
-
"flex-1 resize-none rounded-none border-0 bg-transparent py-3 shadow-none focus-visible:ring-0 dark:bg-transparent",
|
| 151 |
-
className
|
| 152 |
-
)}
|
| 153 |
-
{...props}
|
| 154 |
-
/>
|
| 155 |
-
)
|
| 156 |
-
}
|
| 157 |
-
|
| 158 |
-
export {
|
| 159 |
-
InputGroup,
|
| 160 |
-
InputGroupAddon,
|
| 161 |
-
InputGroupButton,
|
| 162 |
-
InputGroupText,
|
| 163 |
-
InputGroupInput,
|
| 164 |
-
InputGroupTextarea,
|
| 165 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/input-otp.tsx
DELETED
|
@@ -1,69 +0,0 @@
|
|
| 1 |
-
import * as React from "react"
|
| 2 |
-
import { OTPInput, OTPInputContext } from "input-otp"
|
| 3 |
-
import { Minus } from "lucide-react"
|
| 4 |
-
|
| 5 |
-
import { cn } from "@/lib/utils"
|
| 6 |
-
|
| 7 |
-
const InputOTP = React.forwardRef<
|
| 8 |
-
React.ElementRef<typeof OTPInput>,
|
| 9 |
-
React.ComponentPropsWithoutRef<typeof OTPInput>
|
| 10 |
-
>(({ className, containerClassName, ...props }, ref) => (
|
| 11 |
-
<OTPInput
|
| 12 |
-
ref={ref}
|
| 13 |
-
containerClassName={cn(
|
| 14 |
-
"flex items-center gap-2 has-[:disabled]:opacity-50",
|
| 15 |
-
containerClassName
|
| 16 |
-
)}
|
| 17 |
-
className={cn("disabled:cursor-not-allowed", className)}
|
| 18 |
-
{...props}
|
| 19 |
-
/>
|
| 20 |
-
))
|
| 21 |
-
InputOTP.displayName = "InputOTP"
|
| 22 |
-
|
| 23 |
-
const InputOTPGroup = React.forwardRef<
|
| 24 |
-
React.ElementRef<"div">,
|
| 25 |
-
React.ComponentPropsWithoutRef<"div">
|
| 26 |
-
>(({ className, ...props }, ref) => (
|
| 27 |
-
<div ref={ref} className={cn("flex items-center", className)} {...props} />
|
| 28 |
-
))
|
| 29 |
-
InputOTPGroup.displayName = "InputOTPGroup"
|
| 30 |
-
|
| 31 |
-
const InputOTPSlot = React.forwardRef<
|
| 32 |
-
React.ElementRef<"div">,
|
| 33 |
-
React.ComponentPropsWithoutRef<"div"> & { index: number }
|
| 34 |
-
>(({ index, className, ...props }, ref) => {
|
| 35 |
-
const inputOTPContext = React.useContext(OTPInputContext)
|
| 36 |
-
const { char, hasFakeCaret, isActive } = inputOTPContext.slots[index]
|
| 37 |
-
|
| 38 |
-
return (
|
| 39 |
-
<div
|
| 40 |
-
ref={ref}
|
| 41 |
-
className={cn(
|
| 42 |
-
"relative flex h-9 w-9 items-center justify-center border-y border-r border-input text-sm shadow-sm transition-all first:rounded-l-md first:border-l last:rounded-r-md",
|
| 43 |
-
isActive && "z-10 ring-1 ring-ring",
|
| 44 |
-
className
|
| 45 |
-
)}
|
| 46 |
-
{...props}
|
| 47 |
-
>
|
| 48 |
-
{char}
|
| 49 |
-
{hasFakeCaret && (
|
| 50 |
-
<div className="pointer-events-none absolute inset-0 flex items-center justify-center">
|
| 51 |
-
<div className="h-4 w-px animate-caret-blink bg-foreground duration-1000" />
|
| 52 |
-
</div>
|
| 53 |
-
)}
|
| 54 |
-
</div>
|
| 55 |
-
)
|
| 56 |
-
})
|
| 57 |
-
InputOTPSlot.displayName = "InputOTPSlot"
|
| 58 |
-
|
| 59 |
-
const InputOTPSeparator = React.forwardRef<
|
| 60 |
-
React.ElementRef<"div">,
|
| 61 |
-
React.ComponentPropsWithoutRef<"div">
|
| 62 |
-
>(({ ...props }, ref) => (
|
| 63 |
-
<div ref={ref} role="separator" {...props}>
|
| 64 |
-
<Minus />
|
| 65 |
-
</div>
|
| 66 |
-
))
|
| 67 |
-
InputOTPSeparator.displayName = "InputOTPSeparator"
|
| 68 |
-
|
| 69 |
-
export { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
artifacts/mockup-sandbox/src/components/ui/input.tsx
DELETED
|
@@ -1,22 +0,0 @@
|
|
| 1 |
-
import * as React from "react"
|
| 2 |
-
|
| 3 |
-
import { cn } from "@/lib/utils"
|
| 4 |
-
|
| 5 |
-
const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
|
| 6 |
-
({ className, type, ...props }, ref) => {
|
| 7 |
-
return (
|
| 8 |
-
<input
|
| 9 |
-
type={type}
|
| 10 |
-
className={cn(
|
| 11 |
-
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
| 12 |
-
className
|
| 13 |
-
)}
|
| 14 |
-
ref={ref}
|
| 15 |
-
{...props}
|
| 16 |
-
/>
|
| 17 |
-
)
|
| 18 |
-
}
|
| 19 |
-
)
|
| 20 |
-
Input.displayName = "Input"
|
| 21 |
-
|
| 22 |
-
export { Input }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|