feat: add TransformItem close animation
All checks were successful
/ deploy_site (push) Successful in 2m2s

This commit is contained in:
Minhyeok Park 2024-10-30 20:56:12 +09:00
parent 2f6b56d55b
commit 1a936aa112
Signed by: pmh_only
SSH Key Fingerprint: SHA256:g/OyGvi2pcd8ub9mqge/ohmDP0fZX/xOPWPIcM+9XpI
4 changed files with 42 additions and 14 deletions

View File

@ -1,11 +1,12 @@
import styled from "styled-components"; import styled from "styled-components";
export const TextArea = styled.textarea` export const TextArea = styled.textarea`
flex: 1;
border: none; border: none;
resize: none; resize: none;
background-color: transparent; background-color: transparent;
color: #fafafa; color: #fafafa;
width: 100%;
height: 100%;
padding: 10px; padding: 10px;
&:focus { &:focus {

View File

@ -1,4 +1,4 @@
import { FC } from "react"; import { createRef, FC, useEffect, useRef } from "react";
import { Editor as MonacoEditor } from "@monaco-editor/react"; import { Editor as MonacoEditor } from "@monaco-editor/react";
import { useRecoilState } from "recoil"; import { useRecoilState } from "recoil";
import { EditorValueState } from "../GlobalStates/EditorValueState"; import { EditorValueState } from "../GlobalStates/EditorValueState";
@ -6,9 +6,26 @@ import { motion } from "framer-motion";
export const Editor: FC = () => { export const Editor: FC = () => {
const [value, setValue] = useRecoilState(EditorValueState) const [value, setValue] = useRecoilState(EditorValueState)
const ref = useRef<any>()
const containerRef = createRef<HTMLDivElement>()
useEffect(() => {
window.addEventListener('resize', () => {
ref.current?.layout({ width: 0, height: 0 })
window.requestAnimationFrame(() => {
const rect = containerRef.current?.getBoundingClientRect()
ref.current?.layout({
width: rect?.width ?? 0,
height: rect?.height ?? 0
})
})
})
}, [])
return ( return (
<motion.div <motion.div
ref={containerRef}
transition={{ delay: 1.5 }} transition={{ delay: 1.5 }}
initial={{ opacity: 0 }} initial={{ opacity: 0 }}
animate={{ opacity: 1 }}> animate={{ opacity: 1 }}>
@ -16,6 +33,7 @@ export const Editor: FC = () => {
loading={<></>} loading={<></>}
value={value} value={value}
language="yaml" language="yaml"
onMount={(v) => ref.current = v}
onChange={(v) => setValue(v ?? '')} onChange={(v) => setValue(v ?? '')}
options={{ options={{
automaticLayout: true, automaticLayout: true,

View File

@ -15,6 +15,7 @@ import {
WrappedTransformResult WrappedTransformResult
} from "../Transforms/Transform"; } from "../Transforms/Transform";
import { useLocalStorage } from "@uidotdev/usehooks"; import { useLocalStorage } from "@uidotdev/usehooks";
import { AnimatePresence, motion } from "framer-motion";
interface TransformGridItemProp { interface TransformGridItemProp {
transform: WrappedTransform transform: WrappedTransform
@ -169,13 +170,21 @@ export const TransformGridItem: FC<TransformGridItemProp> = ({ transform }) => {
</div> </div>
</div> </div>
{!closed && <AnimatePresence>
<TextArea {!closed &&
readOnly <motion.div
value={result.value} initial={{ height: 0 }}
placeholder="(empty)" animate={{ height: 200 }}
className={clsx(result.error && style.error)} /> exit={{ height: 0 }}
} className={style.output}>
<TextArea
readOnly
value={result.value}
placeholder="(empty)"
className={clsx(result.error && style.error)} />
</motion.div>
}
</AnimatePresence>
</div> </div>
) )
} }

View File

@ -4,11 +4,6 @@
display: flex; display: flex;
padding: 10px; padding: 10px;
flex-direction: column; flex-direction: column;
min-height: 250px;
&.closed {
min-height: inherit;
}
.toolbar { .toolbar {
display: flex; display: flex;
@ -44,6 +39,11 @@
gap: 6px; gap: 6px;
} }
} }
}
.output {
height: 200px;
} }
.error { .error {