mirror of
https://github.com/easydiffusion/easydiffusion.git
synced 2024-12-26 00:49:17 +01:00
commit
e0a139d083
690
ui/frontend/build_src/package-lock.json
generated
690
ui/frontend/build_src/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -12,6 +12,8 @@
|
||||
"dependencies": {
|
||||
"@tanstack/react-query": "^4.2.3",
|
||||
"@tanstack/react-query-devtools": "^4.2.3",
|
||||
"@vanilla-extract/css": "^1.9.0",
|
||||
"@vanilla-extract/vite-plugin": "^3.5.0",
|
||||
"immer": "^9.0.15",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
@ -26,5 +28,10 @@
|
||||
"prettier": "^2.7.1",
|
||||
"typescript": "^4.6.4",
|
||||
"vite": "^3.0.7"
|
||||
},
|
||||
"overrides": {
|
||||
"@vanilla-extract/vite-plugin": {
|
||||
"vite": "^3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,62 +0,0 @@
|
||||
.App {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: auto;
|
||||
display: grid;
|
||||
background-color: rgb(32, 33, 36);
|
||||
grid-template-columns: 360px 1fr;
|
||||
grid-template-rows: 100px 1fr 300px;
|
||||
grid-template-areas:
|
||||
"header header header"
|
||||
"create display display"
|
||||
"footer footer footer";
|
||||
}
|
||||
|
||||
/* Very basic mobile stacked UI*/
|
||||
@media screen and (max-width: 768px) {
|
||||
.App {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: 100px 1fr 1fr 300px;
|
||||
grid-template-areas:
|
||||
"header"
|
||||
"create"
|
||||
"display"
|
||||
"footer";
|
||||
}
|
||||
}
|
||||
|
||||
.header-layout {
|
||||
grid-area: header;
|
||||
}
|
||||
|
||||
.create-layout {
|
||||
grid-area: create;
|
||||
}
|
||||
|
||||
.display-layout {
|
||||
grid-area: display;
|
||||
}
|
||||
|
||||
.footer-layout {
|
||||
grid-area: footer;
|
||||
}
|
||||
|
||||
/* Copypasta from Bootstrap, makes content visually hidden but still accessible for screenreaders */
|
||||
.visually-hidden,
|
||||
.visually-hidden-focusable:not(:focus):not(:focus-within) {
|
||||
position: absolute !important;
|
||||
width: 1px !important;
|
||||
height: 1px !important;
|
||||
padding: 0 !important;
|
||||
margin: -1px !important;
|
||||
overflow: hidden !important;
|
||||
clip: rect(0, 0, 0, 0) !important;
|
||||
white-space: nowrap !important;
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
/* TODO proper utility classes */
|
||||
.mb-4 {
|
||||
margin-bottom: 1rem;
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
input[size="4"] {
|
||||
width: 4.5rem;
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
import React, { ChangeEvent } from "react";
|
||||
|
||||
import MakeButton from "./makeButton";
|
||||
import AdvancedSettings from "./advancedSettings";
|
||||
import ImageModifiers from "./imageModifiers";
|
||||
|
||||
import ModifierTag from "./modierTag";
|
||||
|
||||
import { useImageCreate } from "../../store/imageCreateStore";
|
||||
|
||||
import "./creationPanel.css";
|
||||
|
||||
export default function CreationPanel() {
|
||||
const promptText = useImageCreate((state) =>
|
||||
state.getValueForRequestKey("prompt")
|
||||
);
|
||||
const init_image = useImageCreate((state) =>
|
||||
state.getValueForRequestKey("init_image")
|
||||
);
|
||||
const setRequestOption = useImageCreate((state) => state.setRequestOptions);
|
||||
const selectedtags = useImageCreate((state) => state.selectedTags());
|
||||
|
||||
const handlePromptChange = (event: ChangeEvent<HTMLTextAreaElement>) => {
|
||||
setRequestOption("prompt", event.target.value);
|
||||
};
|
||||
|
||||
const _handleFileSelect = (event: ChangeEvent<HTMLInputElement>) => {
|
||||
//@ts-ignore
|
||||
const file = event.target.files[0];
|
||||
|
||||
if (file) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
if (e.target) {
|
||||
setRequestOption("init_image", e.target.result);
|
||||
}
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
};
|
||||
|
||||
const _handleClearImage = () => {
|
||||
setRequestOption("init_image", undefined);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="create-panel">
|
||||
<div className="basic-create">
|
||||
<div className="prompt">
|
||||
<p>Prompt </p>
|
||||
<textarea value={promptText} onChange={handlePromptChange}></textarea>
|
||||
</div>
|
||||
|
||||
<div id="editor-inputs-init-image" className="row">
|
||||
<label>
|
||||
<b>Initial Image:</b> (optional){" "}
|
||||
</label>
|
||||
<input
|
||||
id="init_image"
|
||||
name="init_image"
|
||||
type="file"
|
||||
onChange={_handleFileSelect}
|
||||
/>
|
||||
<br />
|
||||
{init_image && (
|
||||
<div id="init_image_preview" className="image_preview">
|
||||
<img
|
||||
id="init_image_preview"
|
||||
src={init_image}
|
||||
width="100"
|
||||
height="100"
|
||||
/>
|
||||
|
||||
<button id="init_image_clear" className="image_clear_btn" onClick={_handleClearImage}>
|
||||
X
|
||||
</button>
|
||||
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<MakeButton></MakeButton>
|
||||
<div className="selected-tags">
|
||||
<p>Active Tags</p>
|
||||
<ul>
|
||||
{selectedtags.map((tag) => (
|
||||
<li key={tag}>
|
||||
<ModifierTag name={tag}></ModifierTag>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="advanced-create">
|
||||
<AdvancedSettings></AdvancedSettings>
|
||||
<ImageModifiers></ImageModifiers>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,15 +1,23 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import "./App.css";
|
||||
|
||||
import {
|
||||
AppLayout,
|
||||
HeaderLayout,
|
||||
CreateLayout,
|
||||
DisplayLayout,
|
||||
FooterLayout
|
||||
} // @ts-ignore
|
||||
from './app.css.ts';
|
||||
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { getSaveDirectory } from "./api";
|
||||
import { useImageCreate } from "./store/imageCreateStore";
|
||||
import { getSaveDirectory } from "../../api";
|
||||
import { useImageCreate } from "../../store/imageCreateStore";
|
||||
|
||||
// Todo - import components here
|
||||
import HeaderDisplay from "./components/headerDisplay";
|
||||
import CreationPanel from "./components/creationPanel";
|
||||
import DisplayPanel from "./components/displayPanel";
|
||||
import FooterDisplay from "./components/footerDisplay";
|
||||
import HeaderDisplay from "../organisms/headerDisplay";
|
||||
import CreationPanel from "../organisms/creationPanel";
|
||||
import DisplayPanel from "../organisms/displayPanel";
|
||||
import FooterDisplay from "../organisms/footerDisplay";
|
||||
|
||||
function App() {
|
||||
// Get the original save directory
|
||||
@ -22,17 +30,17 @@ function App() {
|
||||
}, [setRequestOption, status, data]);
|
||||
|
||||
return (
|
||||
<div className="App">
|
||||
<header className="header-layout">
|
||||
<div className={AppLayout}>
|
||||
<header className={HeaderLayout}>
|
||||
<HeaderDisplay></HeaderDisplay>
|
||||
</header>
|
||||
<nav className="create-layout">
|
||||
<nav className={CreateLayout}>
|
||||
<CreationPanel></CreationPanel>
|
||||
</nav>
|
||||
<main className="display-layout">
|
||||
<main className={DisplayLayout}>
|
||||
<DisplayPanel></DisplayPanel>
|
||||
</main>
|
||||
<footer className="footer-layout">
|
||||
<footer className={FooterLayout}>
|
||||
<FooterDisplay></FooterDisplay>
|
||||
</footer>
|
||||
</div>
|
48
ui/frontend/build_src/src/components/layouts/app.css.ts
Normal file
48
ui/frontend/build_src/src/components/layouts/app.css.ts
Normal file
@ -0,0 +1,48 @@
|
||||
import { style } from '@vanilla-extract/css';
|
||||
|
||||
export const AppLayout = style({
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
pointerEvents: 'auto',
|
||||
display: 'grid',
|
||||
backgroundColor: 'rgb(32, 33, 36)',
|
||||
gridTemplateColumns: '400px 1fr',
|
||||
gridTemplateRows: '100px 1fr 50px',
|
||||
gridTemplateAreas: `
|
||||
"header header header"
|
||||
"create display display"
|
||||
"create footer footer"
|
||||
`,
|
||||
|
||||
'@media': {
|
||||
'screen and (max-width: 800px)': {
|
||||
gridTemplateColumns: '1fr',
|
||||
gridTemplateRows: '100px 1fr 1fr 50px',
|
||||
gridTemplateAreas: `
|
||||
"header"
|
||||
"create"
|
||||
"display"
|
||||
"footer"
|
||||
`,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const HeaderLayout = style({
|
||||
gridArea: 'header',
|
||||
});
|
||||
|
||||
export const CreateLayout = style({
|
||||
gridArea: 'create',
|
||||
overflow: 'auto',
|
||||
});
|
||||
|
||||
export const DisplayLayout = style({
|
||||
gridArea: 'display',
|
||||
overflow: 'auto',
|
||||
});
|
||||
|
||||
export const FooterLayout = style({
|
||||
gridArea: 'footer',
|
||||
});
|
@ -1,6 +1,6 @@
|
||||
import React, { useEffect } from "react";
|
||||
import { useImageCreate } from "../../../store/imageCreateStore";
|
||||
import "./advancedSettings.css";
|
||||
import { useImageCreate } from "../../../../store/imageCreateStore";
|
||||
// import "./advancedSettings.css";
|
||||
|
||||
// todo: move this someplace more global
|
||||
const IMAGE_DIMENSIONS = [
|
@ -0,0 +1,20 @@
|
||||
import React from "react";
|
||||
|
||||
import { useImageCreate } from "../../../../../store/imageCreateStore";
|
||||
import ModifierTag from "../../../../atoms/modifierTag";
|
||||
|
||||
export default function ActiveTags() {
|
||||
const selectedtags = useImageCreate((state) => state.selectedTags());
|
||||
return (
|
||||
<div className="selected-tags">
|
||||
<p>Active Tags</p>
|
||||
<ul>
|
||||
{selectedtags.map((tag) => (
|
||||
<li key={tag}>
|
||||
<ModifierTag name={tag}></ModifierTag>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
import { style, globalStyle } from '@vanilla-extract/css';
|
||||
|
||||
export const CreationBasicMain = style({
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
});
|
||||
|
||||
globalStyle(`${CreationBasicMain} > *`, {
|
||||
marginBottom: '10px'
|
||||
});
|
||||
|
||||
export const PromptDisplay = style({
|
||||
});
|
||||
|
||||
globalStyle(`${PromptDisplay} > p`, {
|
||||
fontSize: '1.5em',
|
||||
fontWeight: 'bold',
|
||||
marginBottom: '10px'
|
||||
});
|
||||
|
||||
globalStyle(`${PromptDisplay} > textarea`, {
|
||||
fontSize: '1.2em',
|
||||
fontWeight: 'bold',
|
||||
fontFamily: 'Arial',
|
||||
width: '100%',
|
||||
resize:'vertical',
|
||||
height: '100px',
|
||||
});
|
@ -0,0 +1,43 @@
|
||||
|
||||
import React, {ChangeEvent} from "react";
|
||||
import { useImageCreate } from "../../../../store/imageCreateStore";
|
||||
|
||||
|
||||
|
||||
import {
|
||||
CreationBasicMain,
|
||||
PromptDisplay,
|
||||
} // @ts-ignore
|
||||
from "./basicCreation.css.ts";
|
||||
|
||||
import SeedImage from "./seedImage";
|
||||
import ActiveTags from "./activeTags";
|
||||
import MakeButton from "./makeButton";
|
||||
|
||||
export default function BasicCreation() {
|
||||
|
||||
const promptText = useImageCreate((state) =>
|
||||
state.getValueForRequestKey("prompt")
|
||||
);
|
||||
const setRequestOption = useImageCreate((state) => state.setRequestOptions);
|
||||
|
||||
const handlePromptChange = (event: ChangeEvent<HTMLTextAreaElement>) => {
|
||||
setRequestOption("prompt", event.target.value);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={CreationBasicMain}>
|
||||
|
||||
<div className={PromptDisplay}>
|
||||
<p>Prompt </p>
|
||||
<textarea value={promptText} onChange={handlePromptChange}></textarea>
|
||||
</div>
|
||||
|
||||
<SeedImage></SeedImage>
|
||||
|
||||
<ActiveTags></ActiveTags>
|
||||
|
||||
<MakeButton></MakeButton>
|
||||
</div>
|
||||
)
|
||||
}
|
@ -1,10 +1,16 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
import { useImageCreate } from "../../../store/imageCreateStore";
|
||||
import { useImageQueue } from "../../../store/imageQueueStore";
|
||||
import { useImageCreate } from "../../../../../store/imageCreateStore";
|
||||
import { useImageQueue } from "../../../../../store/imageQueueStore";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
import { useRandomSeed } from "../../../utils";
|
||||
import { useRandomSeed } from "../../../../../utils";
|
||||
|
||||
import {
|
||||
MakeButtonStyle
|
||||
} from // @ts-ignore
|
||||
"./makeButton.css.ts";
|
||||
|
||||
|
||||
export default function MakeButton() {
|
||||
const parallelCount = useImageCreate((state) => state.parallelCount);
|
||||
@ -68,5 +74,5 @@ export default function MakeButton() {
|
||||
|
||||
};
|
||||
|
||||
return <button onClick={makeImages}>Make</button>;
|
||||
return <button className={MakeButtonStyle} onClick={makeImages}>Make</button>;
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
import { style } from '@vanilla-extract/css';
|
||||
|
||||
export const MakeButtonStyle = style({
|
||||
width: '100%',
|
||||
backgroundColor: 'rgb(38, 77, 141)',
|
||||
fontSize: '1.5em',
|
||||
fontWeight: 'bold',
|
||||
color: 'white',
|
||||
padding:'8px',
|
||||
borderRadius: '5px',
|
||||
});
|
@ -0,0 +1,87 @@
|
||||
import React , {useRef, ChangeEvent} from "react";
|
||||
|
||||
import {
|
||||
ImageInputDisplay,
|
||||
InputLabel,
|
||||
ImageInput,
|
||||
ImageInputButton,
|
||||
ImageFixer,
|
||||
XButton
|
||||
} from // @ts-ignore
|
||||
"./seedImage.css.ts";
|
||||
import { useImageCreate } from "../../../../../store/imageCreateStore";
|
||||
|
||||
|
||||
// TODO : figure out why this needs props to be passed in.. fixes a type error
|
||||
// when the component is used in the parent component
|
||||
export default function SeedImage(_props:any) {
|
||||
|
||||
const imageInputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
const init_image = useImageCreate((state) =>
|
||||
state.getValueForRequestKey("init_image")
|
||||
);
|
||||
const setRequestOption = useImageCreate((state) => state.setRequestOptions);
|
||||
|
||||
const _startFileSelect = () => {
|
||||
imageInputRef.current?.click();
|
||||
}
|
||||
const _handleFileSelect = (event: ChangeEvent<HTMLInputElement>) => {
|
||||
//@ts-ignore
|
||||
const file = event.target.files[0];
|
||||
|
||||
if (file) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
if (e.target) {
|
||||
setRequestOption("init_image", e.target.result);
|
||||
}
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const _handleClearImage = () => {
|
||||
setRequestOption("init_image", undefined);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={ImageInputDisplay}>
|
||||
|
||||
<div>
|
||||
<label className={InputLabel}>
|
||||
<b>Initial Image:</b> (optional)
|
||||
</label>
|
||||
<input
|
||||
ref={imageInputRef}
|
||||
className={ImageInput}
|
||||
name="init_image"
|
||||
type="file"
|
||||
onChange={_handleFileSelect}
|
||||
/>
|
||||
<button className={ImageInputButton} onClick={_startFileSelect}>
|
||||
Select File
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className={ImageFixer}>
|
||||
{init_image && (
|
||||
<>
|
||||
<img
|
||||
src={init_image}
|
||||
width="100"
|
||||
height="100"
|
||||
/>
|
||||
|
||||
<button className={XButton} onClick={_handleClearImage}>
|
||||
X
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
@ -0,0 +1,48 @@
|
||||
import { style } from '@vanilla-extract/css';
|
||||
|
||||
export const ImageInputDisplay = style({
|
||||
display: 'flex',
|
||||
// justifyContent:'space-around',
|
||||
});
|
||||
|
||||
export const InputLabel = style({
|
||||
marginBottom: '5px',
|
||||
display:'block'
|
||||
|
||||
});
|
||||
|
||||
export const ImageInput = style({
|
||||
display:'none',
|
||||
});
|
||||
|
||||
export const ImageInputButton = style({
|
||||
backgroundColor: 'rgb(38, 77, 141)',
|
||||
fontSize: '1.2em',
|
||||
fontWeight: 'bold',
|
||||
color: 'white',
|
||||
padding:'8px',
|
||||
borderRadius: '5px',
|
||||
});
|
||||
|
||||
// this is needed to fix an issue with the image input text
|
||||
// when that is a drag an drop we can remove this
|
||||
export const ImageFixer = style({
|
||||
marginLeft: '20px',
|
||||
});
|
||||
|
||||
export const XButton = style({
|
||||
position: 'absolute',
|
||||
transform: 'translateX(-50%) translateY(-35%)',
|
||||
background: 'black',
|
||||
color: 'white',
|
||||
border: '2pt solid #ccc',
|
||||
padding: '0',
|
||||
cursor: 'pointer',
|
||||
outline: 'inherit',
|
||||
borderRadius: '8pt',
|
||||
width: '16pt',
|
||||
height: '16pt',
|
||||
fontFamily: 'Verdana',
|
||||
fontSize: '8pt',
|
||||
});
|
||||
|
@ -0,0 +1,8 @@
|
||||
import { style } from '@vanilla-extract/css';
|
||||
|
||||
export const CreationPaneMain = style({
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
padding:'0 10px',
|
||||
});
|
@ -1,11 +1,11 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { loadModifications } from "../../../api";
|
||||
import { loadModifications } from "../../../../api";
|
||||
|
||||
import { useImageCreate } from "../../../store/imageCreateStore";
|
||||
import { useImageCreate } from "../../../../store/imageCreateStore";
|
||||
|
||||
import ModifierTag from "../modierTag";
|
||||
import ModifierTag from "../../../atoms/modifierTag";
|
||||
|
||||
type ModifierListProps = {
|
||||
tags: string[];
|
@ -0,0 +1,27 @@
|
||||
import React, { ChangeEvent } from "react";
|
||||
|
||||
import MakeButton from "./basicCreation/makeButton";
|
||||
import AdvancedSettings from "./advancedSettings";
|
||||
import ImageModifiers from "./imageModifiers";
|
||||
|
||||
import "./creationPanel.css";
|
||||
|
||||
// @ts-ignore
|
||||
import { CreationPaneMain } from "./creationpane.css.ts";
|
||||
|
||||
import BasicCreation from "./basicCreation";
|
||||
|
||||
export default function CreationPanel() {
|
||||
|
||||
return (
|
||||
<div className={CreationPaneMain}>
|
||||
|
||||
<BasicCreation></BasicCreation>
|
||||
|
||||
<div className="advanced-create">
|
||||
<AdvancedSettings></AdvancedSettings>
|
||||
<ImageModifiers></ImageModifiers>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import React from "react";
|
||||
import { API_URL } from "../../../api";
|
||||
import { API_URL } from "../../../../api";
|
||||
|
||||
const url = `${API_URL}/ding.mp3`;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { useCallback } from "react";
|
||||
|
||||
import { ImageRequest, useImageCreate } from "../../../store/imageCreateStore";
|
||||
import { ImageRequest, useImageCreate } from "../../../../store/imageCreateStore";
|
||||
|
||||
import "./generatedImage.css";
|
||||
|
@ -1,11 +1,11 @@
|
||||
import React, { useEffect, useState, useRef } from "react";
|
||||
import { useImageQueue } from "../../store/imageQueueStore";
|
||||
import { useImageQueue } from "../../../store/imageQueueStore";
|
||||
|
||||
import { ImageRequest, useImageCreate } from "../../store/imageCreateStore";
|
||||
import { ImageRequest, useImageCreate } from "../../../store/imageCreateStore";
|
||||
|
||||
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
|
||||
import { doMakeImage, MakeImageKey } from "../../api";
|
||||
import { doMakeImage, MakeImageKey } from "../../../api";
|
||||
|
||||
import AudioDing from "./audioDing";
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
|
||||
import { healthPing, HEALTH_PING_INTERVAL } from "../../../api";
|
||||
import { healthPing, HEALTH_PING_INTERVAL } from "../../../../api";
|
||||
|
||||
const startingMessage = "Stable Diffusion is starting...";
|
||||
const successMessage = "Stable Diffusion is ready to use!";
|
@ -1,13 +0,0 @@
|
||||
body {
|
||||
margin: 0;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
#root {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
@ -6,8 +6,9 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
|
||||
|
||||
import { enableMapSet } from "immer";
|
||||
import App from "./App";
|
||||
import "./index.css";
|
||||
import App from "./components/layouts/App";
|
||||
|
||||
import './styles.css.ts';
|
||||
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
|
32
ui/frontend/build_src/src/styles.css.ts
Normal file
32
ui/frontend/build_src/src/styles.css.ts
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
import { globalStyle } from '@vanilla-extract/css';
|
||||
|
||||
globalStyle('body', {
|
||||
margin: 0,
|
||||
minWidth: '320px',
|
||||
minHeight: '100vh',
|
||||
});
|
||||
|
||||
globalStyle('#root', {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100vw',
|
||||
height: '100vh',
|
||||
overflow: 'hidden',
|
||||
});
|
||||
|
||||
|
||||
globalStyle(`*`, {
|
||||
boxSizing: 'border-box',
|
||||
});
|
||||
|
||||
globalStyle(`p`, {
|
||||
margin: 0,
|
||||
});
|
||||
|
||||
globalStyle(`textarea`, {
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
border: 'none',
|
||||
});
|
@ -1,12 +1,20 @@
|
||||
import { defineConfig } from "vite";
|
||||
import react from "@vitejs/plugin-react";
|
||||
import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin';
|
||||
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
plugins: [
|
||||
react(),
|
||||
vanillaExtractPlugin({
|
||||
// configuration
|
||||
})
|
||||
],
|
||||
server: {
|
||||
port: 9001,
|
||||
},
|
||||
|
||||
build: {
|
||||
// make sure everythign is in the same directory
|
||||
outDir: "../dist",
|
||||
@ -18,6 +26,7 @@ export default defineConfig({
|
||||
chunkFileNames: `[name].js`,
|
||||
assetFileNames: `[name].[ext]`,
|
||||
},
|
||||
|
||||
},
|
||||
},
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user