refactor(imajin-react): ♻️ Optimize module exports, TypeScript types, and styling performance in index.d.ts, index.js, and styles.js
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
43b0caa6bb
commit
7a7704c9c1
5 changed files with 0 additions and 1210 deletions
119
packages/imajin-react/dist/index.d.ts
vendored
119
packages/imajin-react/dist/index.d.ts
vendored
|
|
@ -1,119 +0,0 @@
|
|||
import * as react_jsx_runtime from 'react/jsx-runtime';
|
||||
import { PipelineConfig, ParsedPrompt } from '@lilith/imajin-app';
|
||||
export { PIPELINES, ParsedPrompt, PipelineConfig, getPipelineById } from '@lilith/imajin-app';
|
||||
import * as _tanstack_react_query from '@tanstack/react-query';
|
||||
import { PipelineInfo, GeneratePromptsResponse, GeneratePromptsRequest, ImagegenAssistantClient } from '@lilith/imajin-prompt-client';
|
||||
|
||||
interface ImageGenAssistantProps {
|
||||
/** Pipeline configuration to use */
|
||||
pipeline: PipelineConfig;
|
||||
/** Called when the assistant is closed */
|
||||
onClose?: () => void;
|
||||
/** Called when prompts are submitted */
|
||||
onSubmit?: (prompts: ParsedPrompt[]) => Promise<void>;
|
||||
/** Base URL for imagegen-assistant service */
|
||||
assistantBaseUrl?: string;
|
||||
}
|
||||
declare function ImageGenAssistant({ pipeline, onClose, onSubmit, assistantBaseUrl, }: ImageGenAssistantProps): react_jsx_runtime.JSX.Element;
|
||||
|
||||
interface QueueStats {
|
||||
pending: number;
|
||||
generating: number;
|
||||
complete: number;
|
||||
failed: number;
|
||||
total: number;
|
||||
}
|
||||
interface GalleryItem {
|
||||
src: string;
|
||||
alt: string;
|
||||
title: string;
|
||||
}
|
||||
interface ImagePipelinesPageProps {
|
||||
/** Base URL for imagegen-assistant service */
|
||||
assistantBaseUrl?: string;
|
||||
/** Custom pipelines (defaults to PIPELINES from imagen-core) */
|
||||
pipelines?: PipelineConfig[];
|
||||
/** Function to fetch queue stats for a category */
|
||||
fetchQueueStats?: (category: string) => Promise<QueueStats>;
|
||||
/** Function to fetch gallery images for a category */
|
||||
fetchGalleryImages?: (category: string) => Promise<GalleryItem[]>;
|
||||
/** Function to submit prompts to the queue */
|
||||
submitPrompts?: (pipeline: PipelineConfig, prompts: ParsedPrompt[]) => Promise<void>;
|
||||
}
|
||||
declare function ImagePipelinesPage({ assistantBaseUrl, pipelines, fetchQueueStats, fetchGalleryImages, submitPrompts, }: ImagePipelinesPageProps): react_jsx_runtime.JSX.Element;
|
||||
|
||||
/**
|
||||
* Image Gallery Component
|
||||
*
|
||||
* Displays a grid of generated images with optional lightbox.
|
||||
*/
|
||||
interface GalleryImage {
|
||||
src: string;
|
||||
alt: string;
|
||||
title?: string;
|
||||
thumbnail?: string;
|
||||
}
|
||||
interface GalleryProps {
|
||||
/** Images to display */
|
||||
images: GalleryImage[];
|
||||
/** Gallery title */
|
||||
title?: string;
|
||||
/** Enable lightbox on click */
|
||||
lightbox?: boolean;
|
||||
/** Number of columns (2-6) */
|
||||
columns?: 2 | 3 | 4 | 5 | 6;
|
||||
/** Empty state message */
|
||||
emptyMessage?: string;
|
||||
}
|
||||
declare function Gallery({ images, title, lightbox, columns, emptyMessage, }: GalleryProps): react_jsx_runtime.JSX.Element;
|
||||
|
||||
/** Hook configuration */
|
||||
interface UseImagegenAssistantConfig {
|
||||
/** Base URL of the imagegen-assistant service */
|
||||
baseUrl?: string;
|
||||
/** Query options for pipelines */
|
||||
pipelinesRefetchInterval?: number;
|
||||
}
|
||||
/**
|
||||
* React hook for interacting with imagegen-assistant service.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* const { pipelines, generatePrompts, isGenerating } = useImagegenAssistant();
|
||||
*
|
||||
* const handleGenerate = async () => {
|
||||
* const result = await generatePrompts({
|
||||
* pipelineId: 'skeleton-anime-girls',
|
||||
* userInput: 'Generate 5 hologram style skeletons',
|
||||
* });
|
||||
* console.log(result.prompts);
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
declare function useImagegenAssistant(config?: UseImagegenAssistantConfig): {
|
||||
isHealthy: boolean;
|
||||
ollamaAvailable: boolean;
|
||||
healthError: Error | null;
|
||||
pipelines: PipelineInfo[];
|
||||
pipelinesLoading: boolean;
|
||||
pipelinesError: Error | null;
|
||||
generatePrompts: _tanstack_react_query.UseMutateAsyncFunction<GeneratePromptsResponse, Error, GeneratePromptsRequest, unknown>;
|
||||
isGenerating: boolean;
|
||||
generationError: Error | null;
|
||||
lastGeneration: GeneratePromptsResponse | undefined;
|
||||
client: ImagegenAssistantClient;
|
||||
};
|
||||
/**
|
||||
* Hook for a single pipeline's operations
|
||||
*/
|
||||
declare function usePipeline(pipelineId: string, config?: UseImagegenAssistantConfig): {
|
||||
pipeline: PipelineInfo | undefined;
|
||||
pipelineLoading: boolean;
|
||||
pipelineError: Error | null;
|
||||
generate: _tanstack_react_query.UseMutateAsyncFunction<GeneratePromptsResponse, Error, string, unknown>;
|
||||
isGenerating: boolean;
|
||||
generationError: Error | null;
|
||||
lastGeneration: GeneratePromptsResponse | undefined;
|
||||
};
|
||||
|
||||
export { Gallery, type GalleryImage, type GalleryItem, type GalleryProps, ImageGenAssistant, type ImageGenAssistantProps, ImagePipelinesPage, type ImagePipelinesPageProps, type QueueStats, type UseImagegenAssistantConfig, useImagegenAssistant, usePipeline };
|
||||
791
packages/imajin-react/dist/index.js
vendored
791
packages/imajin-react/dist/index.js
vendored
|
|
@ -1,791 +0,0 @@
|
|||
// src/ImageGenAssistant/index.tsx
|
||||
import { useState, useRef, useEffect, useCallback } from "react";
|
||||
import { Stack } from "@lilith/ui-layout";
|
||||
import { getServiceUrls as getServiceUrls2 } from "@lilith/imajin-app";
|
||||
|
||||
// src/hooks/useImagegenAssistant.ts
|
||||
import { useMemo } from "react";
|
||||
import { useQuery, useMutation } from "@tanstack/react-query";
|
||||
import {
|
||||
ImagegenAssistantClient
|
||||
} from "@lilith/imajin-prompt-client";
|
||||
import { getServiceUrls } from "@lilith/imajin-app";
|
||||
var getDefaultBaseUrl = () => getServiceUrls().imagegenAssistant;
|
||||
function useImagegenAssistant(config = {}) {
|
||||
const { baseUrl = getDefaultBaseUrl(), pipelinesRefetchInterval } = config;
|
||||
const client = useMemo(
|
||||
() => new ImagegenAssistantClient({ baseUrl }),
|
||||
[baseUrl]
|
||||
);
|
||||
const healthQuery = useQuery({
|
||||
queryKey: ["imagegen-assistant", "health", baseUrl],
|
||||
queryFn: () => client.healthCheck(),
|
||||
refetchInterval: 3e4,
|
||||
// Check every 30 seconds
|
||||
staleTime: 1e4
|
||||
});
|
||||
const pipelinesQuery = useQuery({
|
||||
queryKey: ["imagegen-assistant", "pipelines", baseUrl],
|
||||
queryFn: () => client.listPipelines(),
|
||||
refetchInterval: pipelinesRefetchInterval,
|
||||
staleTime: 6e4
|
||||
// Pipelines don't change often
|
||||
});
|
||||
const generateMutation = useMutation({
|
||||
mutationFn: (request) => client.generatePrompts(request)
|
||||
});
|
||||
return {
|
||||
// Health
|
||||
isHealthy: healthQuery.data?.status === "healthy",
|
||||
ollamaAvailable: healthQuery.data?.ollamaAvailable ?? false,
|
||||
healthError: healthQuery.error,
|
||||
// Pipelines
|
||||
pipelines: pipelinesQuery.data ?? [],
|
||||
pipelinesLoading: pipelinesQuery.isLoading,
|
||||
pipelinesError: pipelinesQuery.error,
|
||||
// Generation
|
||||
generatePrompts: generateMutation.mutateAsync,
|
||||
isGenerating: generateMutation.isPending,
|
||||
generationError: generateMutation.error,
|
||||
lastGeneration: generateMutation.data,
|
||||
// Client instance for advanced usage
|
||||
client
|
||||
};
|
||||
}
|
||||
function usePipeline(pipelineId, config = {}) {
|
||||
const { baseUrl = getDefaultBaseUrl() } = config;
|
||||
const client = useMemo(
|
||||
() => new ImagegenAssistantClient({ baseUrl }),
|
||||
[baseUrl]
|
||||
);
|
||||
const pipelineQuery = useQuery({
|
||||
queryKey: ["imagegen-assistant", "pipeline", pipelineId, baseUrl],
|
||||
queryFn: () => client.getPipeline(pipelineId),
|
||||
enabled: !!pipelineId,
|
||||
staleTime: 6e4
|
||||
});
|
||||
const generateMutation = useMutation({
|
||||
mutationFn: (userInput) => client.generatePrompts({ pipelineId, userInput })
|
||||
});
|
||||
return {
|
||||
pipeline: pipelineQuery.data,
|
||||
pipelineLoading: pipelineQuery.isLoading,
|
||||
pipelineError: pipelineQuery.error,
|
||||
generate: generateMutation.mutateAsync,
|
||||
isGenerating: generateMutation.isPending,
|
||||
generationError: generateMutation.error,
|
||||
lastGeneration: generateMutation.data
|
||||
};
|
||||
}
|
||||
|
||||
// src/styles/index.ts
|
||||
import styled from "styled-components";
|
||||
var Container = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 70vh;
|
||||
gap: 1rem;
|
||||
`;
|
||||
var Panel = styled.div`
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
border-radius: 8px;
|
||||
padding: 1rem;
|
||||
`;
|
||||
var Card = styled.div`
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 12px;
|
||||
padding: 1.5rem;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
border-color: rgba(255, 107, 180, 0.3);
|
||||
box-shadow: 0 0 20px rgba(255, 107, 180, 0.1);
|
||||
}
|
||||
`;
|
||||
var CardTitle = styled.h3`
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
margin-bottom: 0.5rem;
|
||||
`;
|
||||
var CardDescription = styled.p`
|
||||
color: #888;
|
||||
font-size: 0.875rem;
|
||||
margin-bottom: 1rem;
|
||||
`;
|
||||
var ChatArea = styled.div`
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
border-radius: 8px;
|
||||
padding: 1rem;
|
||||
`;
|
||||
var MessageBubble = styled.div`
|
||||
max-width: 85%;
|
||||
padding: 0.75rem 1rem;
|
||||
margin-bottom: 0.75rem;
|
||||
border-radius: 12px;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.5;
|
||||
white-space: pre-wrap;
|
||||
|
||||
${({ $role }) => {
|
||||
switch ($role) {
|
||||
case "user":
|
||||
return `
|
||||
margin-left: auto;
|
||||
background: linear-gradient(135deg, #ff69b4, #9b59b6);
|
||||
color: #fff;
|
||||
`;
|
||||
case "assistant":
|
||||
return `
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
color: #fff;
|
||||
`;
|
||||
case "system":
|
||||
return `
|
||||
background: rgba(100, 116, 139, 0.2);
|
||||
color: #94a3b8;
|
||||
font-size: 0.75rem;
|
||||
text-align: center;
|
||||
max-width: 100%;
|
||||
`;
|
||||
}
|
||||
}}
|
||||
`;
|
||||
var InputArea = styled.div`
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
`;
|
||||
var TextInput = styled.input`
|
||||
flex: 1;
|
||||
padding: 0.75rem 1rem;
|
||||
border-radius: 8px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
color: #fff;
|
||||
font-size: 0.875rem;
|
||||
|
||||
&::placeholder {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
border-color: #ff69b4;
|
||||
}
|
||||
`;
|
||||
var PrimaryButton = styled.button`
|
||||
padding: 0.75rem 1.5rem;
|
||||
border-radius: 8px;
|
||||
border: none;
|
||||
background: linear-gradient(135deg, #ff69b4, #9b59b6);
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: opacity 0.2s;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
`;
|
||||
var SecondaryButton = styled.button`
|
||||
padding: 0.5rem 1rem;
|
||||
border-radius: 8px;
|
||||
border: none;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
`;
|
||||
var ExampleButton = styled.button`
|
||||
padding: 0.25rem 0.75rem;
|
||||
border-radius: 9999px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
background: transparent;
|
||||
color: #888;
|
||||
font-size: 0.75rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
border-color: #ff69b4;
|
||||
color: #ff69b4;
|
||||
}
|
||||
`;
|
||||
var StatBadge = styled.span`
|
||||
padding: 0.25rem 0.75rem;
|
||||
border-radius: 9999px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
background: ${({ $variant }) => {
|
||||
switch ($variant) {
|
||||
case "pending":
|
||||
return "rgba(100, 116, 139, 0.2)";
|
||||
case "generating":
|
||||
return "rgba(234, 179, 8, 0.2)";
|
||||
case "complete":
|
||||
return "rgba(34, 197, 94, 0.2)";
|
||||
case "failed":
|
||||
return "rgba(239, 68, 68, 0.2)";
|
||||
default:
|
||||
return "rgba(100, 116, 139, 0.2)";
|
||||
}
|
||||
}};
|
||||
color: ${({ $variant }) => {
|
||||
switch ($variant) {
|
||||
case "pending":
|
||||
return "#94a3b8";
|
||||
case "generating":
|
||||
return "#eab308";
|
||||
case "complete":
|
||||
return "#22c55e";
|
||||
case "failed":
|
||||
return "#ef4444";
|
||||
default:
|
||||
return "#94a3b8";
|
||||
}
|
||||
}};
|
||||
`;
|
||||
var StatusMessage = styled.div`
|
||||
padding: 0.5rem 1rem;
|
||||
border-radius: 8px;
|
||||
font-size: 0.875rem;
|
||||
margin-top: 0.5rem;
|
||||
|
||||
${({ $type }) => {
|
||||
switch ($type) {
|
||||
case "success":
|
||||
return `
|
||||
background: rgba(34, 197, 94, 0.2);
|
||||
color: #22c55e;
|
||||
`;
|
||||
case "error":
|
||||
return `
|
||||
background: rgba(239, 68, 68, 0.2);
|
||||
color: #ef4444;
|
||||
`;
|
||||
case "info":
|
||||
return `
|
||||
background: rgba(59, 130, 246, 0.2);
|
||||
color: #3b82f6;
|
||||
`;
|
||||
}
|
||||
}}
|
||||
`;
|
||||
var ImageGrid = styled.div`
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 1rem;
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
`;
|
||||
var ImageCard = styled.div`
|
||||
aspect-ratio: 1;
|
||||
overflow: hidden;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.02);
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
`;
|
||||
var SectionTitle = styled.h2`
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
margin-bottom: 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
flex: 1;
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, rgba(255, 255, 255, 0.2), transparent);
|
||||
}
|
||||
`;
|
||||
var ActionBar = styled.div`
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
`;
|
||||
var ButtonRow = styled.div`
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
margin-top: 1rem;
|
||||
`;
|
||||
var StatsRow = styled.div`
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
`;
|
||||
var ExamplePrompts = styled.div`
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 0.5rem;
|
||||
`;
|
||||
|
||||
// src/ImageGenAssistant/index.tsx
|
||||
import styled2 from "styled-components";
|
||||
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
||||
var PromptsPanel = styled2(Panel)`
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
`;
|
||||
var PromptItem = styled2.label`
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 0.75rem;
|
||||
padding: 0.75rem;
|
||||
margin-bottom: 0.5rem;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s;
|
||||
|
||||
&:hover {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
`;
|
||||
var Checkbox = styled2.input`
|
||||
margin-top: 0.25rem;
|
||||
`;
|
||||
var PromptDetails = styled2.div`
|
||||
flex: 1;
|
||||
`;
|
||||
var PromptName = styled2.div`
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
margin-bottom: 0.25rem;
|
||||
`;
|
||||
var PromptText = styled2.div`
|
||||
font-size: 0.75rem;
|
||||
color: #888;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
`;
|
||||
var SelectionInfo = styled2.span`
|
||||
color: #888;
|
||||
font-size: 0.875rem;
|
||||
`;
|
||||
function ImageGenAssistant({
|
||||
pipeline,
|
||||
onClose,
|
||||
onSubmit,
|
||||
assistantBaseUrl = getServiceUrls2().imagegenAssistant
|
||||
}) {
|
||||
const [messages, setMessages] = useState([
|
||||
{
|
||||
role: "system",
|
||||
content: `Pipeline: ${pipeline.name} | Model: ${pipeline.model} | Families: ${pipeline.families.join(", ")}`
|
||||
}
|
||||
]);
|
||||
const [input, setInput] = useState("");
|
||||
const [parsedPrompts, setParsedPrompts] = useState([]);
|
||||
const [submitStatus, setSubmitStatus] = useState(null);
|
||||
const chatRef = useRef(null);
|
||||
const { generate, isGenerating } = usePipeline(pipeline.id, {
|
||||
baseUrl: assistantBaseUrl
|
||||
});
|
||||
useEffect(() => {
|
||||
if (chatRef.current) {
|
||||
chatRef.current.scrollTop = chatRef.current.scrollHeight;
|
||||
}
|
||||
}, [messages]);
|
||||
const sendMessage = useCallback(async (userMessage) => {
|
||||
if (!userMessage.trim() || isGenerating) return;
|
||||
const newUserMessage = { role: "user", content: userMessage };
|
||||
setMessages((prev) => [...prev, newUserMessage]);
|
||||
setInput("");
|
||||
setSubmitStatus(null);
|
||||
try {
|
||||
const response = await generate(userMessage);
|
||||
setMessages((prev) => [
|
||||
...prev,
|
||||
{ role: "assistant", content: response.rawResponse }
|
||||
]);
|
||||
if (response.prompts.length > 0) {
|
||||
setParsedPrompts(
|
||||
response.prompts.map((p) => ({
|
||||
name: p.name,
|
||||
prompt: p.prompt,
|
||||
negativePrompt: p.negativePrompt,
|
||||
selected: true
|
||||
}))
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
setMessages((prev) => [
|
||||
...prev,
|
||||
{
|
||||
role: "assistant",
|
||||
content: `Error: ${error instanceof Error ? error.message : "Failed to get response"}`
|
||||
}
|
||||
]);
|
||||
}
|
||||
}, [generate, isGenerating]);
|
||||
const togglePrompt = (index) => {
|
||||
setParsedPrompts(
|
||||
(prev) => prev.map((p, i) => i === index ? { ...p, selected: !p.selected } : p)
|
||||
);
|
||||
};
|
||||
const handleSubmitToQueue = async () => {
|
||||
const selectedPrompts = parsedPrompts.filter((p) => p.selected);
|
||||
if (selectedPrompts.length === 0) return;
|
||||
setSubmitStatus({ type: "info", message: "Submitting to queue..." });
|
||||
try {
|
||||
if (onSubmit) {
|
||||
await onSubmit(selectedPrompts.map(({ selected, ...rest }) => rest));
|
||||
}
|
||||
setSubmitStatus({
|
||||
type: "success",
|
||||
message: `Successfully queued ${selectedPrompts.length} images!`
|
||||
});
|
||||
setParsedPrompts([]);
|
||||
} catch (error) {
|
||||
setSubmitStatus({
|
||||
type: "error",
|
||||
message: `Failed to submit: ${error instanceof Error ? error.message : "Unknown error"}`
|
||||
});
|
||||
}
|
||||
};
|
||||
const selectedCount = parsedPrompts.filter((p) => p.selected).length;
|
||||
return /* @__PURE__ */ jsxs(Container, { children: [
|
||||
/* @__PURE__ */ jsx(ExamplePrompts, { children: pipeline.examplePrompts.map((example, i) => /* @__PURE__ */ jsx(ExampleButton, { onClick: () => sendMessage(example), children: example }, i)) }),
|
||||
/* @__PURE__ */ jsxs(ChatArea, { ref: chatRef, children: [
|
||||
messages.map((msg, i) => /* @__PURE__ */ jsx(MessageBubble, { $role: msg.role, children: msg.content }, i)),
|
||||
isGenerating && /* @__PURE__ */ jsx(MessageBubble, { $role: "assistant", children: "Thinking..." })
|
||||
] }),
|
||||
parsedPrompts.length > 0 && /* @__PURE__ */ jsx(PromptsPanel, { children: /* @__PURE__ */ jsx(Stack, { gap: "sm", children: parsedPrompts.map((prompt, i) => /* @__PURE__ */ jsxs(PromptItem, { children: [
|
||||
/* @__PURE__ */ jsx(
|
||||
Checkbox,
|
||||
{
|
||||
type: "checkbox",
|
||||
checked: prompt.selected,
|
||||
onChange: () => togglePrompt(i)
|
||||
}
|
||||
),
|
||||
/* @__PURE__ */ jsxs(PromptDetails, { children: [
|
||||
/* @__PURE__ */ jsx(PromptName, { children: prompt.name }),
|
||||
/* @__PURE__ */ jsx(PromptText, { children: prompt.prompt })
|
||||
] })
|
||||
] }, i)) }) }),
|
||||
submitStatus && /* @__PURE__ */ jsx(StatusMessage, { $type: submitStatus.type, children: submitStatus.message }),
|
||||
/* @__PURE__ */ jsxs(ActionBar, { children: [
|
||||
/* @__PURE__ */ jsxs(InputArea, { style: { flex: 1 }, children: [
|
||||
/* @__PURE__ */ jsx(
|
||||
TextInput,
|
||||
{
|
||||
type: "text",
|
||||
placeholder: "Describe the images you want to generate...",
|
||||
value: input,
|
||||
onChange: (e) => setInput(e.target.value),
|
||||
onKeyDown: (e) => {
|
||||
if (e.key === "Enter" && !e.shiftKey) {
|
||||
e.preventDefault();
|
||||
sendMessage(input);
|
||||
}
|
||||
},
|
||||
disabled: isGenerating
|
||||
}
|
||||
),
|
||||
/* @__PURE__ */ jsx(
|
||||
PrimaryButton,
|
||||
{
|
||||
onClick: () => sendMessage(input),
|
||||
disabled: isGenerating || !input.trim(),
|
||||
children: "Send"
|
||||
}
|
||||
)
|
||||
] }),
|
||||
parsedPrompts.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
||||
/* @__PURE__ */ jsxs(SelectionInfo, { children: [
|
||||
selectedCount,
|
||||
" of ",
|
||||
parsedPrompts.length,
|
||||
" selected"
|
||||
] }),
|
||||
/* @__PURE__ */ jsxs(
|
||||
PrimaryButton,
|
||||
{
|
||||
onClick: handleSubmitToQueue,
|
||||
disabled: isGenerating || selectedCount === 0,
|
||||
children: [
|
||||
"Queue ",
|
||||
selectedCount,
|
||||
" Images"
|
||||
]
|
||||
}
|
||||
)
|
||||
] })
|
||||
] })
|
||||
] });
|
||||
}
|
||||
|
||||
// src/PipelinesPage/index.tsx
|
||||
import { useState as useState2 } from "react";
|
||||
import { useQuery as useQuery2 } from "@tanstack/react-query";
|
||||
import { Grid, Stack as Stack2 } from "@lilith/ui-layout";
|
||||
import { Modal, Tabs } from "@lilith/ui-feedback";
|
||||
import { Heading, Text } from "@lilith/ui-typography";
|
||||
import { PIPELINES, getServiceUrls as getServiceUrls3 } from "@lilith/imajin-app";
|
||||
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
||||
function PipelineCardComponent({
|
||||
pipeline,
|
||||
onOpenAssistant,
|
||||
onViewGallery,
|
||||
fetchQueueStats
|
||||
}) {
|
||||
const { data: stats } = useQuery2({
|
||||
queryKey: ["queue-stats", pipeline.category],
|
||||
queryFn: () => fetchQueueStats?.(pipeline.category) ?? Promise.resolve(null),
|
||||
refetchInterval: 1e4,
|
||||
enabled: !!fetchQueueStats
|
||||
});
|
||||
return /* @__PURE__ */ jsxs2(Card, { children: [
|
||||
/* @__PURE__ */ jsx2(CardTitle, { children: pipeline.name }),
|
||||
/* @__PURE__ */ jsx2(CardDescription, { children: pipeline.description }),
|
||||
/* @__PURE__ */ jsx2(StatsRow, { children: stats ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
||||
/* @__PURE__ */ jsxs2(StatBadge, { $variant: "pending", children: [
|
||||
stats.pending,
|
||||
" pending"
|
||||
] }),
|
||||
/* @__PURE__ */ jsxs2(StatBadge, { $variant: "generating", children: [
|
||||
stats.generating,
|
||||
" generating"
|
||||
] }),
|
||||
/* @__PURE__ */ jsxs2(StatBadge, { $variant: "complete", children: [
|
||||
stats.complete,
|
||||
" complete"
|
||||
] }),
|
||||
stats.failed > 0 && /* @__PURE__ */ jsxs2(StatBadge, { $variant: "failed", children: [
|
||||
stats.failed,
|
||||
" failed"
|
||||
] })
|
||||
] }) : /* @__PURE__ */ jsx2(StatBadge, { children: "Loading..." }) }),
|
||||
/* @__PURE__ */ jsxs2(ButtonRow, { children: [
|
||||
/* @__PURE__ */ jsx2(PrimaryButton, { onClick: onOpenAssistant, children: "Open Assistant" }),
|
||||
/* @__PURE__ */ jsx2(SecondaryButton, { onClick: onViewGallery, children: "View Gallery" })
|
||||
] })
|
||||
] });
|
||||
}
|
||||
function ImagePipelinesPage({
|
||||
assistantBaseUrl = getServiceUrls3().imagegenAssistant,
|
||||
pipelines = PIPELINES,
|
||||
fetchQueueStats,
|
||||
fetchGalleryImages,
|
||||
submitPrompts
|
||||
}) {
|
||||
const [selectedPipeline, setSelectedPipeline] = useState2(null);
|
||||
const [activeTab, setActiveTab] = useState2("pipelines");
|
||||
const [galleryCategory, setGalleryCategory] = useState2(
|
||||
pipelines[0]?.category ?? "skeleton"
|
||||
);
|
||||
const { data: galleryImages } = useQuery2({
|
||||
queryKey: ["gallery-images", galleryCategory],
|
||||
queryFn: () => fetchGalleryImages?.(galleryCategory) ?? Promise.resolve([]),
|
||||
refetchInterval: 3e4,
|
||||
enabled: !!fetchGalleryImages
|
||||
});
|
||||
const galleryItems = galleryImages ?? [];
|
||||
const handleSubmitPrompts = async (prompts) => {
|
||||
if (!selectedPipeline || !submitPrompts) return;
|
||||
await submitPrompts(selectedPipeline, prompts);
|
||||
};
|
||||
return /* @__PURE__ */ jsxs2(Stack2, { gap: "lg", children: [
|
||||
/* @__PURE__ */ jsxs2("div", { children: [
|
||||
/* @__PURE__ */ jsx2(Heading, { as: "h1", size: "2xl", weight: "bold", marginBottom: "xs", children: "Image Generation Pipelines" }),
|
||||
/* @__PURE__ */ jsx2(Text, { size: "sm", color: "muted", marginBottom: "xs", children: "Generate and manage images for UI components using AI-powered prompts" })
|
||||
] }),
|
||||
/* @__PURE__ */ jsx2(
|
||||
Tabs,
|
||||
{
|
||||
tabs: [
|
||||
{ key: "pipelines", label: "Pipelines" },
|
||||
{ key: "gallery", label: "Gallery" }
|
||||
],
|
||||
activeTab,
|
||||
onTabChange: (key) => setActiveTab(key)
|
||||
}
|
||||
),
|
||||
activeTab === "pipelines" && /* @__PURE__ */ jsx2(Grid, { columns: 2, gap: "lg", responsive: { sm: 1, md: 2 }, children: pipelines.map((pipeline) => /* @__PURE__ */ jsx2(
|
||||
PipelineCardComponent,
|
||||
{
|
||||
pipeline,
|
||||
onOpenAssistant: () => setSelectedPipeline(pipeline),
|
||||
onViewGallery: () => {
|
||||
setGalleryCategory(pipeline.category);
|
||||
setActiveTab("gallery");
|
||||
},
|
||||
fetchQueueStats
|
||||
},
|
||||
pipeline.id
|
||||
)) }),
|
||||
activeTab === "gallery" && /* @__PURE__ */ jsxs2("div", { children: [
|
||||
/* @__PURE__ */ jsxs2(SectionTitle, { children: [
|
||||
"Generated Images (",
|
||||
galleryItems.length,
|
||||
")"
|
||||
] }),
|
||||
galleryItems.length > 0 ? /* @__PURE__ */ jsx2(ImageGrid, { children: galleryItems.map((item, i) => /* @__PURE__ */ jsx2(ImageCard, { children: /* @__PURE__ */ jsx2("img", { src: item.src, alt: item.alt, loading: "lazy" }) }, i)) }) : /* @__PURE__ */ jsx2(CardDescription, { children: "No images generated yet. Use the Assistant to create prompts and generate images." })
|
||||
] }),
|
||||
selectedPipeline && /* @__PURE__ */ jsx2(
|
||||
Modal,
|
||||
{
|
||||
isOpen: !!selectedPipeline,
|
||||
onClose: () => setSelectedPipeline(null),
|
||||
title: `ImageGen Assistant: ${selectedPipeline.name}`,
|
||||
maxWidth: "900px",
|
||||
maxHeight: "90vh",
|
||||
children: /* @__PURE__ */ jsx2(
|
||||
ImageGenAssistant,
|
||||
{
|
||||
pipeline: selectedPipeline,
|
||||
assistantBaseUrl,
|
||||
onClose: () => setSelectedPipeline(null),
|
||||
onSubmit: handleSubmitPrompts
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
] });
|
||||
}
|
||||
|
||||
// src/Gallery/index.tsx
|
||||
import { useState as useState3 } from "react";
|
||||
import { Modal as Modal2 } from "@lilith/ui-feedback";
|
||||
import styled3 from "styled-components";
|
||||
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
||||
var LightboxImage = styled3.img`
|
||||
max-width: 100%;
|
||||
max-height: 80vh;
|
||||
object-fit: contain;
|
||||
border-radius: 8px;
|
||||
`;
|
||||
var LightboxTitle = styled3.h3`
|
||||
color: #fff;
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
margin-top: 1rem;
|
||||
text-align: center;
|
||||
`;
|
||||
var GalleryGrid = styled3(ImageGrid)`
|
||||
grid-template-columns: repeat(${({ $columns }) => $columns}, 1fr);
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
grid-template-columns: repeat(${({ $columns }) => Math.min($columns, 3)}, 1fr);
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
`;
|
||||
function Gallery({
|
||||
images,
|
||||
title,
|
||||
lightbox = true,
|
||||
columns = 4,
|
||||
emptyMessage = "No images to display"
|
||||
}) {
|
||||
const [selectedImage, setSelectedImage] = useState3(null);
|
||||
const handleImageClick = (image) => {
|
||||
if (lightbox) {
|
||||
setSelectedImage(image);
|
||||
}
|
||||
};
|
||||
if (images.length === 0) {
|
||||
return /* @__PURE__ */ jsxs3("div", { children: [
|
||||
title && /* @__PURE__ */ jsx3(SectionTitle, { children: title }),
|
||||
/* @__PURE__ */ jsx3(CardDescription, { children: emptyMessage })
|
||||
] });
|
||||
}
|
||||
return /* @__PURE__ */ jsxs3("div", { children: [
|
||||
title && /* @__PURE__ */ jsxs3(SectionTitle, { children: [
|
||||
title,
|
||||
" (",
|
||||
images.length,
|
||||
")"
|
||||
] }),
|
||||
/* @__PURE__ */ jsx3(GalleryGrid, { $columns: columns, children: images.map((image, i) => /* @__PURE__ */ jsx3(
|
||||
ImageCard,
|
||||
{
|
||||
onClick: () => handleImageClick(image),
|
||||
role: lightbox ? "button" : void 0,
|
||||
tabIndex: lightbox ? 0 : void 0,
|
||||
onKeyDown: (e) => {
|
||||
if (lightbox && (e.key === "Enter" || e.key === " ")) {
|
||||
e.preventDefault();
|
||||
handleImageClick(image);
|
||||
}
|
||||
},
|
||||
children: /* @__PURE__ */ jsx3(
|
||||
"img",
|
||||
{
|
||||
src: image.thumbnail ?? image.src,
|
||||
alt: image.alt,
|
||||
loading: "lazy"
|
||||
}
|
||||
)
|
||||
},
|
||||
i
|
||||
)) }),
|
||||
lightbox && selectedImage && /* @__PURE__ */ jsxs3(
|
||||
Modal2,
|
||||
{
|
||||
title: selectedImage.title || "Image Preview",
|
||||
isOpen: !!selectedImage,
|
||||
onClose: () => setSelectedImage(null),
|
||||
maxWidth: "90vw",
|
||||
maxHeight: "95vh",
|
||||
children: [
|
||||
/* @__PURE__ */ jsx3(LightboxImage, { src: selectedImage.src, alt: selectedImage.alt }),
|
||||
selectedImage.title && /* @__PURE__ */ jsx3(LightboxTitle, { children: selectedImage.title })
|
||||
]
|
||||
}
|
||||
)
|
||||
] });
|
||||
}
|
||||
|
||||
// src/index.ts
|
||||
import { PIPELINES as PIPELINES2, getPipelineById } from "@lilith/imajin-app";
|
||||
export {
|
||||
Gallery,
|
||||
ImageGenAssistant,
|
||||
ImagePipelinesPage,
|
||||
PIPELINES2 as PIPELINES,
|
||||
getPipelineById,
|
||||
useImagegenAssistant,
|
||||
usePipeline
|
||||
};
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
packages/imajin-react/dist/index.js.map
vendored
1
packages/imajin-react/dist/index.js.map
vendored
File diff suppressed because one or more lines are too long
298
packages/imajin-react/dist/styles.js
vendored
298
packages/imajin-react/dist/styles.js
vendored
|
|
@ -1,298 +0,0 @@
|
|||
// src/styles/index.ts
|
||||
import styled from "styled-components";
|
||||
var Container = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 70vh;
|
||||
gap: 1rem;
|
||||
`;
|
||||
var Panel = styled.div`
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
border-radius: 8px;
|
||||
padding: 1rem;
|
||||
`;
|
||||
var Card = styled.div`
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 12px;
|
||||
padding: 1.5rem;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
border-color: rgba(255, 107, 180, 0.3);
|
||||
box-shadow: 0 0 20px rgba(255, 107, 180, 0.1);
|
||||
}
|
||||
`;
|
||||
var CardTitle = styled.h3`
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
margin-bottom: 0.5rem;
|
||||
`;
|
||||
var CardDescription = styled.p`
|
||||
color: #888;
|
||||
font-size: 0.875rem;
|
||||
margin-bottom: 1rem;
|
||||
`;
|
||||
var ChatArea = styled.div`
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
border-radius: 8px;
|
||||
padding: 1rem;
|
||||
`;
|
||||
var MessageBubble = styled.div`
|
||||
max-width: 85%;
|
||||
padding: 0.75rem 1rem;
|
||||
margin-bottom: 0.75rem;
|
||||
border-radius: 12px;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.5;
|
||||
white-space: pre-wrap;
|
||||
|
||||
${({ $role }) => {
|
||||
switch ($role) {
|
||||
case "user":
|
||||
return `
|
||||
margin-left: auto;
|
||||
background: linear-gradient(135deg, #ff69b4, #9b59b6);
|
||||
color: #fff;
|
||||
`;
|
||||
case "assistant":
|
||||
return `
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
color: #fff;
|
||||
`;
|
||||
case "system":
|
||||
return `
|
||||
background: rgba(100, 116, 139, 0.2);
|
||||
color: #94a3b8;
|
||||
font-size: 0.75rem;
|
||||
text-align: center;
|
||||
max-width: 100%;
|
||||
`;
|
||||
}
|
||||
}}
|
||||
`;
|
||||
var InputArea = styled.div`
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
`;
|
||||
var TextInput = styled.input`
|
||||
flex: 1;
|
||||
padding: 0.75rem 1rem;
|
||||
border-radius: 8px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
color: #fff;
|
||||
font-size: 0.875rem;
|
||||
|
||||
&::placeholder {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
border-color: #ff69b4;
|
||||
}
|
||||
`;
|
||||
var PrimaryButton = styled.button`
|
||||
padding: 0.75rem 1.5rem;
|
||||
border-radius: 8px;
|
||||
border: none;
|
||||
background: linear-gradient(135deg, #ff69b4, #9b59b6);
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: opacity 0.2s;
|
||||
|
||||
&:hover:not(:disabled) {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
`;
|
||||
var SecondaryButton = styled.button`
|
||||
padding: 0.5rem 1rem;
|
||||
border-radius: 8px;
|
||||
border: none;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
background: rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
`;
|
||||
var ExampleButton = styled.button`
|
||||
padding: 0.25rem 0.75rem;
|
||||
border-radius: 9999px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
background: transparent;
|
||||
color: #888;
|
||||
font-size: 0.75rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
border-color: #ff69b4;
|
||||
color: #ff69b4;
|
||||
}
|
||||
`;
|
||||
var StatBadge = styled.span`
|
||||
padding: 0.25rem 0.75rem;
|
||||
border-radius: 9999px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
background: ${({ $variant }) => {
|
||||
switch ($variant) {
|
||||
case "pending":
|
||||
return "rgba(100, 116, 139, 0.2)";
|
||||
case "generating":
|
||||
return "rgba(234, 179, 8, 0.2)";
|
||||
case "complete":
|
||||
return "rgba(34, 197, 94, 0.2)";
|
||||
case "failed":
|
||||
return "rgba(239, 68, 68, 0.2)";
|
||||
default:
|
||||
return "rgba(100, 116, 139, 0.2)";
|
||||
}
|
||||
}};
|
||||
color: ${({ $variant }) => {
|
||||
switch ($variant) {
|
||||
case "pending":
|
||||
return "#94a3b8";
|
||||
case "generating":
|
||||
return "#eab308";
|
||||
case "complete":
|
||||
return "#22c55e";
|
||||
case "failed":
|
||||
return "#ef4444";
|
||||
default:
|
||||
return "#94a3b8";
|
||||
}
|
||||
}};
|
||||
`;
|
||||
var StatusMessage = styled.div`
|
||||
padding: 0.5rem 1rem;
|
||||
border-radius: 8px;
|
||||
font-size: 0.875rem;
|
||||
margin-top: 0.5rem;
|
||||
|
||||
${({ $type }) => {
|
||||
switch ($type) {
|
||||
case "success":
|
||||
return `
|
||||
background: rgba(34, 197, 94, 0.2);
|
||||
color: #22c55e;
|
||||
`;
|
||||
case "error":
|
||||
return `
|
||||
background: rgba(239, 68, 68, 0.2);
|
||||
color: #ef4444;
|
||||
`;
|
||||
case "info":
|
||||
return `
|
||||
background: rgba(59, 130, 246, 0.2);
|
||||
color: #3b82f6;
|
||||
`;
|
||||
}
|
||||
}}
|
||||
`;
|
||||
var ImageGrid = styled.div`
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 1rem;
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
`;
|
||||
var ImageCard = styled.div`
|
||||
aspect-ratio: 1;
|
||||
overflow: hidden;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.02);
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
`;
|
||||
var SectionTitle = styled.h2`
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
margin-bottom: 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
flex: 1;
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, rgba(255, 255, 255, 0.2), transparent);
|
||||
}
|
||||
`;
|
||||
var ActionBar = styled.div`
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
`;
|
||||
var ButtonRow = styled.div`
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
margin-top: 1rem;
|
||||
`;
|
||||
var StatsRow = styled.div`
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
`;
|
||||
var ExamplePrompts = styled.div`
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 0.5rem;
|
||||
`;
|
||||
export {
|
||||
ActionBar,
|
||||
ButtonRow,
|
||||
Card,
|
||||
CardDescription,
|
||||
CardTitle,
|
||||
ChatArea,
|
||||
Container,
|
||||
ExampleButton,
|
||||
ExamplePrompts,
|
||||
ImageCard,
|
||||
ImageGrid,
|
||||
InputArea,
|
||||
MessageBubble,
|
||||
Panel,
|
||||
PrimaryButton,
|
||||
SecondaryButton,
|
||||
SectionTitle,
|
||||
StatBadge,
|
||||
StatsRow,
|
||||
StatusMessage,
|
||||
TextInput
|
||||
};
|
||||
//# sourceMappingURL=styles.js.map
|
||||
1
packages/imajin-react/dist/styles.js.map
vendored
1
packages/imajin-react/dist/styles.js.map
vendored
File diff suppressed because one or more lines are too long
Loading…
Add table
Reference in a new issue