diff --git a/package.json b/package.json index 06f30f7..6ab9eb1 100644 --- a/package.json +++ b/package.json @@ -24,8 +24,10 @@ "@radix-ui/react-select": "^2.0.0", "@radix-ui/react-separator": "^1.0.3", "@radix-ui/react-slider": "^1.1.2", + "@radix-ui/react-tabs": "^1.0.4", "@radix-ui/react-toggle": "^1.0.3", "@radix-ui/react-toggle-group": "^1.0.4", + "@radix-ui/react-toolbar": "^1.0.4", "@radix-ui/themes": "^2.0.0", "@reduxjs/toolkit": "^1.9.6", "@remotion/google-fonts": "^4.0.51", @@ -49,6 +51,7 @@ "react-dom": "18.2.0", "react-icons": "^4.11.0", "react-konva": "^18.2.10", + "react-konva-utils": "^1.0.5", "react-redux": "^8.1.3", "superjson": "^1.13.1", "tailwind-merge": "^1.14.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 89d91aa..3e42ae5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -44,12 +44,18 @@ dependencies: '@radix-ui/react-slider': specifier: ^1.1.2 version: 1.1.2(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-tabs': + specifier: ^1.0.4 + version: 1.0.4(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-toggle': specifier: ^1.0.3 version: 1.0.3(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/react-toggle-group': specifier: ^1.0.4 version: 1.0.4(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-toolbar': + specifier: ^1.0.4 + version: 1.0.4(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) '@radix-ui/themes': specifier: ^2.0.0 version: 2.0.0(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) @@ -119,6 +125,9 @@ dependencies: react-konva: specifier: ^18.2.10 version: 18.2.10(konva@9.2.2)(react-dom@18.2.0)(react@18.2.0) + react-konva-utils: + specifier: ^1.0.5 + version: 1.0.5(konva@9.2.2)(react-dom@18.2.0)(react@18.2.0) react-redux: specifier: ^8.1.3 version: 8.1.3(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0)(redux@4.2.1) @@ -1558,6 +1567,33 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false + /@radix-ui/react-toolbar@1.0.4(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-tBgmM/O7a07xbaEkYJWYTXkIdU/1pW4/KZORR43toC/4XWyBCURK0ei9kMUdp+gTPPKBgYLxXmRSH1EVcIDp8Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.23.2 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-context': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.31)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-roving-focus': 1.0.4(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-separator': 1.0.3(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-toggle-group': 1.0.4(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.31 + '@types/react-dom': 18.2.14 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@radix-ui/react-tooltip@1.0.7(@types/react-dom@18.2.14)(@types/react@18.2.31)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-lPh5iKNFVQ/jav/j6ZrWq3blfDJ0OH9R6FlNUHPMqdLuQ9vwDgFsRxvl8b7Asuy5c8xmoojHUxKHQSOAvMHxyw==} peerDependencies: @@ -4126,6 +4162,20 @@ packages: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} dev: false + /react-konva-utils@1.0.5(konva@9.2.2)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-MQco0bre5ohm2lS34wAr/QJgT5PCnKbS3V1/aeYDldc8mq5X1UwcjxZWSL7YxGw3jQSHOm6XyX0YgLXQYUWBuQ==} + peerDependencies: + konva: ^8.3.5 || ^9.0.0 + react: ^18.2.0 + react-dom: ^18.2.0 + dependencies: + konva: 9.2.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-konva: 18.2.10(konva@9.2.2)(react-dom@18.2.0)(react@18.2.0) + use-image: 1.1.1(react-dom@18.2.0)(react@18.2.0) + dev: false + /react-konva@18.2.10(konva@9.2.2)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-ohcX1BJINL43m4ynjZ24MxFI1syjBdrXhqVxYVDw2rKgr3yuS0x/6m1Y2Z4sl4T/gKhfreBx8KHisd0XC6OT1g==} peerDependencies: diff --git a/public/logo.png b/public/logo.png new file mode 100644 index 0000000..26c9df0 Binary files /dev/null and b/public/logo.png differ diff --git a/src/components/EditableText.tsx b/src/components/EditableText.tsx new file mode 100644 index 0000000..4a46828 --- /dev/null +++ b/src/components/EditableText.tsx @@ -0,0 +1,56 @@ +import React, { ComponentPropsWithoutRef, CSSProperties } from "react"; +import { Html } from "react-konva-utils"; + +function getStyle( + width: CSSProperties["width"], + height: CSSProperties["height"], +) { + const isFirefox = navigator.userAgent.toLowerCase().indexOf("firefox") > -1; + const baseStyle: CSSProperties = { + width: `${width}px`, + height: `${height}px`, + border: "none", + padding: "0px", + margin: "0px", + background: "none", + outline: "none", + resize: "none", + color: "black", + fontSize: "24px", + fontFamily: "sans-serif", + }; + if (isFirefox) { + return baseStyle; + } + return { + ...baseStyle, + marginTop: "-4px", + }; +} + +export function EditableTextInput({ + x, + y, + width, + height, + value, + onChange, + onKeyDown, +}: { + x: number; + y: number; + width: CSSProperties["width"]; + height: CSSProperties["height"]; +} & ComponentPropsWithoutRef<"textarea">) { + const style = getStyle(width, height); + return ( + +