diff --git a/components/Textarea.tsx b/components/Textarea.tsx new file mode 100644 index 0000000..0e53b51 --- /dev/null +++ b/components/Textarea.tsx @@ -0,0 +1,115 @@ +import { styled } from "../stitches.config"; + +export const Textarea = styled("textarea", { + // Reset + appearance: "none", + borderWidth: "0", + boxSizing: "border-box", + fontFamily: "inherit", + outline: "none", + width: "100%", + flex: "1", + backgroundColor: "$mauve4", + display: "inline-flex", + alignItems: "center", + justifyContent: "center", + borderRadius: "$sm", + px: "$2", + fontSize: "$md", + lineHeight: 1, + color: "$mauve12", + boxShadow: `0 0 0 1px $colors$mauve8`, + WebkitTapHighlightColor: "rgba(0,0,0,0)", + "&::before": { + boxSizing: "border-box", + }, + "&::after": { + boxSizing: "border-box", + }, + fontVariantNumeric: "tabular-nums", + + "&:-webkit-autofill": { + boxShadow: "inset 0 0 0 1px $colors$blue6, inset 0 0 0 100px $colors$blue3", + }, + + "&:-webkit-autofill::first-line": { + fontFamily: "$untitled", + color: "$mauve12", + }, + + "&:focus": { + boxShadow: `0 0 0 1px $colors$mauve10`, + "&:-webkit-autofill": { + boxShadow: `0 0 0 1px $colors$mauve10`, + }, + }, + "&::placeholder": { + color: "$mauve9", + }, + "&:disabled": { + pointerEvents: "none", + backgroundColor: "$mauve2", + color: "$mauve8", + cursor: "not-allowed", + "&::placeholder": { + color: "$mauve7", + }, + }, + + variants: { + variant: { + ghost: { + boxShadow: "none", + backgroundColor: "transparent", + "@hover": { + "&:hover": { + boxShadow: "inset 0 0 0 1px $colors$mauve7", + }, + }, + "&:focus": { + backgroundColor: "$loContrast", + boxShadow: `0 0 0 1px $colors$mauve10`, + }, + "&:disabled": { + backgroundColor: "transparent", + }, + "&:read-only": { + backgroundColor: "transparent", + }, + }, + deep: { + backgroundColor: "$deep", + boxShadow: "none", + }, + }, + state: { + invalid: { + boxShadow: "inset 0 0 0 1px $colors$crimson7", + "&:focus": { + boxShadow: + "inset 0px 0px 0px 1px $colors$crimson8, 0px 0px 0px 1px $colors$crimson8", + }, + }, + valid: { + boxShadow: "inset 0 0 0 1px $colors$grass7", + "&:focus": { + boxShadow: + "inset 0px 0px 0px 1px $colors$grass8, 0px 0px 0px 1px $colors$grass8", + }, + }, + }, + cursor: { + default: { + cursor: "default", + "&:focus": { + cursor: "text", + }, + }, + text: { + cursor: "text", + }, + }, + }, +}); + +export default Textarea; \ No newline at end of file diff --git a/components/Transaction/ui.tsx b/components/Transaction/ui.tsx index ee08688..132cd06 100644 --- a/components/Transaction/ui.tsx +++ b/components/Transaction/ui.tsx @@ -15,6 +15,7 @@ import { useSnapshot } from "valtio"; import state from "../../state"; import { streamState } from "../DebugStream"; import { Button } from ".."; +import Textarea from "../Textarea"; interface UIProps { setState: ( @@ -110,6 +111,9 @@ export const TxUI: FC = ({ k => !specialFields.includes(k) ) as [keyof TxFields]; + const switchToJson = () => + setState({ editorSavedValue: null, viewType: "json" }); + return ( = ({ let value: string | undefined; if (typeof _value === "object") { if (_value.$type === "json" && typeof _value.$value === "object") { - value = JSON.stringify(_value.$value); + value = JSON.stringify(_value.$value, null, 2); } else { value = _value.$value.toString(); } @@ -204,9 +208,13 @@ export const TxUI: FC = ({ value = _value?.toString(); } - let isXrp = typeof _value === "object" && _value.$type === "xrp"; - + const isXrp = typeof _value === "object" && _value.$type === "xrp"; + const isJson = typeof _value === "object" && _value.$type === "json"; const isFee = field === "Fee"; + let rows = isJson + ? (value?.match(/\n/gm)?.length || 0) + 1 + : undefined; + if (rows && rows > 5) rows = 5; return ( = ({ {field + (isXrp ? " (XRP)" : "")}:{" "} - { - handleSetField(field, e.target.value); - }} - css={{ width: "70%", flex: "inherit" }} - /> + {isJson ? ( +