Create FloatingLabelInput for scenario variables (#68)

* Create FloatingLabelInput

* Fix prettier

* Simplify changes
This commit is contained in:
arcticfly
2023-07-20 12:20:12 -07:00
committed by GitHub
parent e598e454d0
commit 55c077d604
4 changed files with 63 additions and 34 deletions

View File

@@ -0,0 +1,49 @@
import { FormLabel, FormControl, type TextareaProps } from "@chakra-ui/react";
import { useState } from "react";
import AutoResizeTextArea from "../AutoResizeTextArea";
export const FloatingLabelInput = ({
label,
value,
...props
}: { label: string; value: string } & TextareaProps) => {
const [isFocused, setIsFocused] = useState(false);
return (
<FormControl position="relative">
<FormLabel
position="absolute"
left="10px"
top={isFocused || !!value ? 0 : 3}
transform={isFocused || !!value ? "translateY(-50%)" : "translateY(0)"}
fontSize={isFocused || !!value ? "12px" : "16px"}
transition="all 0.15s"
zIndex="100"
bg="white"
px={1}
mt={0}
mb={2}
lineHeight="1"
pointerEvents="none"
color={isFocused ? "blue.500" : "gray.500"}
>
{label}
</FormLabel>
<AutoResizeTextArea
px={3}
pt={3}
pb={2}
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
borderRadius="md"
borderColor={isFocused ? "blue.500" : "gray.400"}
autoComplete="off"
value={value}
maxHeight={32}
overflowY="auto"
overflowX="hidden"
{...props}
/>
</FormControl>
);
};

View File

@@ -9,7 +9,7 @@ import { Box, Button, Flex, HStack, Icon, Spinner, Stack, Tooltip, VStack } from
import { cellPadding } from "../constants";
import { BsX } from "react-icons/bs";
import { RiDraggable } from "react-icons/ri";
import AutoResizeTextArea from "../AutoResizeTextArea";
import { FloatingLabelInput } from "./FloatingLabelInput";
export default function ScenarioEditor({
scenario,
@@ -77,6 +77,7 @@ export default function ScenarioEditor({
pr={cellPadding.x}
py={cellPadding.y}
pl={canModify ? 0 : cellPadding.x}
spacing={0}
height="100%"
draggable={!variableInputHovered}
onDragStart={(e) => {
@@ -131,7 +132,7 @@ export default function ScenarioEditor({
{variableLabels.length === 0 ? (
<Box color="gray.500">{vars.data ? "No scenario variables configured" : "Loading..."}</Box>
) : (
<VStack spacing={1}>
<VStack spacing={4} flex={1} py={2}>
{variableLabels.map((key) => {
const value = values[key] ?? "";
const layoutDirection = value.length > 20 ? "column" : "row";
@@ -143,31 +144,14 @@ export default function ScenarioEditor({
flexWrap="wrap"
width="full"
>
<Box
bgColor="blue.100"
color="blue.600"
px={1}
my="3px"
fontSize="xs"
fontWeight="bold"
>
{key}
</Box>
<AutoResizeTextArea
px={2}
py={1}
placeholder="empty"
borderRadius="sm"
fontSize="sm"
lineHeight={1.2}
value={value}
<FloatingLabelInput
label={key}
isDisabled={!canModify}
_disabled={{ opacity: 1, cursor: "default" }}
style={{ width: "100%" }}
value={value}
onChange={(e) => {
setValues((prev) => ({ ...prev, [key]: e.target.value }));
}}
maxH="32"
overflowY="auto"
onKeyDown={(e) => {
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
e.preventDefault();
@@ -175,12 +159,6 @@ export default function ScenarioEditor({
onSave();
}
}}
resize="none"
overflow="hidden"
flex={layoutDirection === "row" ? 1 : undefined}
borderColor={hasChanged ? "blue.300" : "transparent"}
_hover={{ borderColor: "gray.300" }}
_focus={{ borderColor: "blue.500", outline: "none", bg: "white" }}
onMouseEnter={() => setVariableInputHovered(true)}
onMouseLeave={() => setVariableInputHovered(false)}
/>

View File

@@ -2,11 +2,10 @@ import { type Session } from "next-auth";
import { SessionProvider } from "next-auth/react";
import { type AppType } from "next/app";
import { api } from "~/utils/api";
import { ChakraProvider } from "@chakra-ui/react";
import theme from "~/utils/theme";
import Favicon from "~/components/Favicon";
import "~/utils/analytics";
import Head from "next/head";
import { ChakraThemeProvider } from "~/theme/ChakraThemeProvider";
const MyApp: AppType<{ session: Session | null }> = ({
Component,
@@ -22,9 +21,9 @@ const MyApp: AppType<{ session: Session | null }> = ({
</Head>
<SessionProvider session={session}>
<Favicon />
<ChakraProvider theme={theme}>
<ChakraThemeProvider>
<Component {...pageProps} />
</ChakraProvider>
</ChakraThemeProvider>
</SessionProvider>
</>
);

View File

@@ -1,5 +1,6 @@
import { extendTheme } from "@chakra-ui/react";
import "@fontsource/inconsolata";
import { ChakraProvider } from "@chakra-ui/react";
const systemFont =
'ui-sans-serif, -apple-system, "system-ui", "Segoe UI", Helvetica, "Apple Color Emoji", Arial, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"';
@@ -34,4 +35,6 @@ const theme = extendTheme({
},
});
export default theme;
export const ChakraThemeProvider = ({ children }: { children: JSX.Element }) => {
return <ChakraProvider theme={theme}>{children}</ChakraProvider>;
};