diff --git a/.eslintrc.js b/.eslintrc.js
index 46722ae2da..92f30898c7 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,5 +1,5 @@
module.exports = {
root: true,
// This tells ESLint to load the config from the package `eslint-config-custom`
- extends: ["custom"],
+ extends: ["@webstudio-is/eslint-config-custom"],
};
diff --git a/.github/actions/publish/action.yaml b/.github/actions/publish/action.yaml
new file mode 100644
index 0000000000..24a129d324
--- /dev/null
+++ b/.github/actions/publish/action.yaml
@@ -0,0 +1,28 @@
+name: 'Release NPM package'
+description: 'Release NPM package'
+inputs:
+ package:
+ description: 'Package.json location (relative)'
+ default: 'package.json'
+ required: true
+ token:
+ description: 'NPM Token'
+ default: 'null'
+ required: true
+runs:
+ using: "composite"
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-node@v3
+ with:
+ node-version: 16
+ - name: Install Dependencies
+ run: yarn install
+ shell: bash
+ - uses: JS-DevTools/npm-publish@v1
+ with:
+ token: ${{ inputs.token }}
+ dry-run: false
+ check-version: true
+ access: 'public'
+ package: ${{ inputs.package }}
\ No newline at end of file
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index cef4574ccc..9436f72f4e 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -14,7 +14,7 @@
## Before merging
-- [ ] tested locally and on preview environment (preview dev login: 5de6e)
+- [ ] tested locally and on preview environment (preview dev login: 5de6)
- [ ] updated [test cases](https://github.com/webstudio-is/webstudio-designer/blob/main/apps/designer/docs/test-cases.md) document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env.example` and the `designer/env-check.js` if mandatory
diff --git a/.github/workflows/design-system.yml b/.github/workflows/design-system.yml
new file mode 100644
index 0000000000..109456bc75
--- /dev/null
+++ b/.github/workflows/design-system.yml
@@ -0,0 +1,16 @@
+name: Design System Publish
+on:
+ push:
+ paths:
+ - "packages/design-system/**/*"
+ - ".github/workflows/design-system.yml"
+ - ".github/actions/publish/action.yaml"
+jobs:
+ publish:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: ./.github/actions/publish
+ with:
+ package: "./packages/design-system/package.json"
+ token: ${{ secrets.NPM_TOKEN }}
diff --git a/.github/workflows/eslint-config-custom.yml b/.github/workflows/eslint-config-custom.yml
new file mode 100644
index 0000000000..3effb53420
--- /dev/null
+++ b/.github/workflows/eslint-config-custom.yml
@@ -0,0 +1,16 @@
+name: Eslint Config Publish
+on:
+ push:
+ paths:
+ - "packages/eslint-config-custom/**/*"
+ - ".github/workflows/eslint-config-custom.yml"
+ - ".github/actions/publish/action.yaml"
+jobs:
+ publish:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: ./.github/actions/publish
+ with:
+ package: "./packages/eslint-config-custom/package.json"
+ token: ${{ secrets.NPM_TOKEN }}
diff --git a/.github/workflows/icons.yml b/.github/workflows/icons.yml
new file mode 100644
index 0000000000..3deb808f0b
--- /dev/null
+++ b/.github/workflows/icons.yml
@@ -0,0 +1,16 @@
+name: Icons Publish
+on:
+ push:
+ paths:
+ - "packages/icons/**/*"
+ - ".github/workflows/icons-publish.yml"
+ - ".github/actions/publish/action.yaml"
+jobs:
+ publish:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: ./.github/actions/publish
+ with:
+ package: "./packages/icons/package.json"
+ token: ${{ secrets.NPM_TOKEN }}
diff --git a/.github/workflows/jest-config.yml b/.github/workflows/jest-config.yml
new file mode 100644
index 0000000000..2d5a1079cb
--- /dev/null
+++ b/.github/workflows/jest-config.yml
@@ -0,0 +1,16 @@
+name: Jest Config Publish
+on:
+ push:
+ paths:
+ - "packages/jest-config/**/*"
+ - ".github/workflows/jest-config.yml"
+ - ".github/actions/publish/action.yaml"
+jobs:
+ publish:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: ./.github/actions/publish
+ with:
+ package: "./packages/jest-config/package.json"
+ token: ${{ secrets.NPM_TOKEN }}
diff --git a/.github/workflows/react-sdk-publish.yml b/.github/workflows/react-sdk-publish.yml
deleted file mode 100644
index ff7d173cff..0000000000
--- a/.github/workflows/react-sdk-publish.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-name: SDK publish
-on:
- push:
- paths:
- - 'packages/react-sdk/**/*'
- - '.github/workflows/react-sdk-publish.yml'
-jobs:
- publish:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - uses: actions/setup-node@v3
- with:
- node-version: 16
- - name: Install Dependencies
- run: yarn install
- - uses: JS-DevTools/npm-publish@v1
- with:
- token: ${{ secrets.NPM_TOKEN }}
- dry-run: false
- check-version: true
- package: './packages/react-sdk/package.json'
\ No newline at end of file
diff --git a/.github/workflows/react-sdk.yml b/.github/workflows/react-sdk.yml
new file mode 100644
index 0000000000..9a122a632b
--- /dev/null
+++ b/.github/workflows/react-sdk.yml
@@ -0,0 +1,16 @@
+name: SDK publish
+on:
+ push:
+ paths:
+ - "packages/react-sdk/**/*"
+ - ".github/workflows/react-sdk.yml"
+ - ".github/actions/publish/action.yaml"
+jobs:
+ publish:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: ./.github/actions/publish
+ with:
+ package: "./packages/react-sdk/package.json"
+ token: ${{ secrets.NPM_TOKEN }}
diff --git a/.github/workflows/tsconfig.yml b/.github/workflows/tsconfig.yml
new file mode 100644
index 0000000000..f9b6ed774e
--- /dev/null
+++ b/.github/workflows/tsconfig.yml
@@ -0,0 +1,16 @@
+name: Tsconfig Publish
+on:
+ push:
+ paths:
+ - "packages/tsconfig/**/*"
+ - ".github/workflows/tsconfig.yml"
+ - ".github/actions/publish/action.yaml"
+jobs:
+ publish:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: ./.github/actions/publish
+ with:
+ package: "./packages/tsconfig/package.json"
+ token: ${{ secrets.NPM_TOKEN }}
diff --git a/apps/designer/app/designer/features/inspector/inspector.tsx b/apps/designer/app/designer/features/inspector/inspector.tsx
index f9e428fe36..66dd3caf17 100644
--- a/apps/designer/app/designer/features/inspector/inspector.tsx
+++ b/apps/designer/app/designer/features/inspector/inspector.tsx
@@ -28,9 +28,9 @@ export const Inspector = ({ publish }: InspectorProps) => {
if (selectedInstanceData === undefined) {
return (
-
+
{/* @todo: use this space for something more usefull: a-la figma's no instance selected sate, maybe create an issue with a more specific proposal? */}
-
+
Select an instance on the canvas
diff --git a/apps/designer/app/designer/features/sidebar-left/panels/asset-manager.tsx b/apps/designer/app/designer/features/sidebar-left/panels/asset-manager.tsx
index 5cd97686ea..df64934c85 100644
--- a/apps/designer/app/designer/features/sidebar-left/panels/asset-manager.tsx
+++ b/apps/designer/app/designer/features/sidebar-left/panels/asset-manager.tsx
@@ -2,48 +2,53 @@ import { ImageIcon } from "@webstudio-is/icons";
import { Flex, Grid, Heading } from "@webstudio-is/design-system";
import { useEffect, useState } from "react";
import { useActionData } from "@remix-run/react";
-import { Asset } from "@webstudio-is/prisma-client";
-import { AssetManagerImage } from "./components/image";
+import { AssetManagerThumbnail } from "./components/thumbnail";
import { AddAnAssetForm } from "./components/add-an-asset-form";
-import { UploadingAsset } from "../types";
+import { Asset } from "../types";
+
+export const useAssetsState = (baseAssets: Array) => {
+ const imageChanges = useActionData();
+
+ const [assets, setAssets] = useState(baseAssets);
+
+ useEffect(() => {
+ if (imageChanges?.uploadedAssets?.length) {
+ setAssets((currentAssets) => [
+ ...imageChanges.uploadedAssets,
+ ...currentAssets.filter((asset) => asset.status !== "uploading"),
+ ]);
+ }
+ if (imageChanges?.deletedAsset?.id) {
+ setAssets((currentAssets) => [
+ ...currentAssets.filter(
+ (asset) => asset.id !== imageChanges.deletedAsset.id
+ ),
+ ]);
+ }
+ }, [imageChanges]);
+
+ const onUploadAsset = (uploadedAssets: Array) =>
+ setAssets((assets) => [...uploadedAssets, ...assets]);
+
+ return { assets, onUploadAsset };
+};
export const TabContent = ({
assets: baseAssets,
}: {
- assets: Array;
+ assets: Array;
}) => {
- const newImages = useActionData();
-
- const [assets, setAssets] = useState(baseAssets);
-
- useEffect(() => {
- if (newImages?.length) {
- setAssets((currentAssets) => [
- ...newImages,
- ...currentAssets.filter((asset) => asset.status !== "uploading"),
- ]);
- }
- }, [newImages]);
-
+ const { assets, onUploadAsset } = useAssetsState(baseAssets);
return (
-
+
Assets
- ) =>
- setAssets((assets) => [...uploadedAssets, ...assets])
- }
- />
+
{assets.map((asset) => (
-
+
))}
diff --git a/apps/designer/app/designer/features/sidebar-left/panels/components/image.tsx b/apps/designer/app/designer/features/sidebar-left/panels/components/image.tsx
deleted file mode 100644
index c52cf3925c..0000000000
--- a/apps/designer/app/designer/features/sidebar-left/panels/components/image.tsx
+++ /dev/null
@@ -1,79 +0,0 @@
-import { useEffect, useState } from "react";
-import { Box, ProgressBar } from "@webstudio-is/design-system";
-import { useInterval } from "react-use";
-import placeholderImage from "~/shared/images/image-placeholder.svg";
-import brokenImage from "~/shared/images/broken-image-placeholder.svg";
-import { Asset } from "@webstudio-is/prisma-client";
-
-const useImageWithFallback = ({ path }: { path: string }) => {
- const [src, setSrc] = useState(placeholderImage);
-
- useEffect(() => {
- const newImage = new Image();
- newImage.onload = () => setSrc(path);
- newImage.onerror = () => setSrc(brokenImage);
- newImage.src = path;
- }, [path]);
-
- return src;
-};
-
-export const AssetManagerImage = ({
- path,
- alt,
- status,
-}: {
- path: string;
- alt?: string;
- status?: Asset["status"];
-}) => {
- const isUploading = status === "uploading";
- const src = useImageWithFallback({ path });
- const [progressBarPercentage, setProgressBarPercentage] = useState(0);
-
- // @todo rewrite this fake indication to show real progress
- useInterval(
- () => {
- setProgressBarPercentage((percentage) =>
- percentage < 60 ? percentage + 1 : percentage
- );
- },
- isUploading ? 100 : null
- );
-
- return (
-
-
- {isUploading && (
-
- )}
-
- );
-};
diff --git a/apps/designer/app/designer/features/sidebar-left/panels/components/thumbnail.tsx b/apps/designer/app/designer/features/sidebar-left/panels/components/thumbnail.tsx
new file mode 100644
index 0000000000..894f95ea71
--- /dev/null
+++ b/apps/designer/app/designer/features/sidebar-left/panels/components/thumbnail.tsx
@@ -0,0 +1,142 @@
+import { useEffect, useState } from "react";
+import {
+ Box,
+ Button,
+ Flex,
+ ProgressBar,
+ Tooltip,
+} from "@webstudio-is/design-system";
+import { useInterval } from "react-use";
+import placeholderImage from "~/shared/images/image-placeholder.svg";
+import brokenImage from "~/shared/images/broken-image-placeholder.svg";
+import { useSubmit } from "@remix-run/react";
+import { Asset } from "~/designer/features/sidebar-left/types";
+import { Cross2Icon } from "@radix-ui/react-icons";
+
+const useImageWithFallback = ({ path }: { path: string }) => {
+ const [src, setSrc] = useState(placeholderImage);
+
+ useEffect(() => {
+ const newImage = new Image();
+ newImage.onload = () => setSrc(path);
+ newImage.onerror = () => setSrc(brokenImage);
+ newImage.src = path;
+ }, [path]);
+
+ return src;
+};
+
+const useFakeProgress = ({
+ isUploading,
+ isDeleting,
+}: {
+ isUploading: boolean;
+ isDeleting: boolean;
+}) => {
+ const [progressBarPercentage, setProgressBarPercentage] = useState(0);
+
+ // @todo rewrite this fake indication to show real progress
+ useInterval(
+ () => {
+ setProgressBarPercentage((percentage) =>
+ percentage < 60 ? percentage + 1 : percentage
+ );
+ },
+ isUploading || isDeleting ? 100 : null
+ );
+
+ return progressBarPercentage;
+};
+
+export const AssetManagerThumbnail = ({
+ path,
+ alt,
+ status,
+ name,
+ id,
+}: Asset) => {
+ const submit = useSubmit();
+ const [isDeleting, setIsDeleting] = useState(false);
+ const isUploading = status === "uploading";
+ const src = useImageWithFallback({ path });
+ const [isTooltipOpen, setTolltipOpen] = useState(false);
+ const progressBarPercentage = useFakeProgress({ isUploading, isDeleting });
+
+ const closeTooltip = () => setTolltipOpen(false);
+
+ const deleteAsset = () => {
+ const formData = new FormData();
+ formData.append("assetId", id);
+ formData.append("assetName", name);
+ closeTooltip();
+ setIsDeleting(true);
+ submit(formData, { method: "delete" });
+ };
+
+ return (
+
+
+ {!isUploading && (
+
+ Are you sure you want to delete this asset?
+
+
+ }
+ >
+
+
+ )}
+ {(isUploading || isDeleting) && (
+
+ )}
+
+ );
+};
diff --git a/apps/designer/app/designer/features/sidebar-left/types.ts b/apps/designer/app/designer/features/sidebar-left/types.ts
index 29fd62a28d..4783a96849 100644
--- a/apps/designer/app/designer/features/sidebar-left/types.ts
+++ b/apps/designer/app/designer/features/sidebar-left/types.ts
@@ -1,9 +1,10 @@
-import { Asset } from "@webstudio-is/prisma-client";
+import { Asset as BaseAsset } from "@webstudio-is/prisma-client";
import { panels } from "./panels";
export type TabName = keyof typeof panels | "none";
export type UploadingAsset = Pick<
- Asset,
+ BaseAsset,
"id" | "status" | "name" | "path" | "alt"
>;
+export type Asset = BaseAsset | UploadingAsset;
diff --git a/apps/designer/app/root.tsx b/apps/designer/app/root.tsx
index a73cf3cffd..9013b2cf39 100644
--- a/apps/designer/app/root.tsx
+++ b/apps/designer/app/root.tsx
@@ -1,4 +1,5 @@
// Our root outlet doesn't contain a layout because we have 2 types of documents: canvas and designer and we need to decide down the line which one to render, thre is no single root document.
+import { TooltipProvider } from "@radix-ui/react-tooltip";
import { Outlet } from "@remix-run/react";
import { withSentryRouteTracing } from "@sentry/remix";
import { ErrorBoundary } from "@sentry/remix";
@@ -7,7 +8,9 @@ import { OutletProps } from "react-router-dom";
const RootWithErrorBoundary = (props: OutletProps) => (
// @ts-expect-error 'ErrorBoundary' cannot be used as a JSX component.
-
+
+
+
);
diff --git a/apps/designer/app/routes/dashboard/index.tsx b/apps/designer/app/routes/dashboard/index.tsx
index 6dfbbf0ef8..92d903e1bf 100644
--- a/apps/designer/app/routes/dashboard/index.tsx
+++ b/apps/designer/app/routes/dashboard/index.tsx
@@ -10,12 +10,16 @@ import * as db from "~/shared/db";
import config from "~/config";
import { ensureUserCookie } from "~/shared/session";
import { authenticator } from "~/services/auth.server";
+import { zfd } from "zod-form-data";
export { links };
+const schema = zfd.formData({
+ project: zfd.text(),
+});
+
export const action: ActionFunction = async ({ request }) => {
- const formData = await request.formData();
- const title = formData.get("project");
- if (typeof title !== "string") return { errors: "Title required" };
+ const { project: title } = schema.parse(await request.formData());
+
const { userId, headers } = await ensureUserCookie(request);
const authenticatedUser = await authenticator.isAuthenticated(request);
try {
diff --git a/apps/designer/app/routes/designer/$id.tsx b/apps/designer/app/routes/designer/$id.tsx
index 322389f433..40fb5a4597 100644
--- a/apps/designer/app/routes/designer/$id.tsx
+++ b/apps/designer/app/routes/designer/$id.tsx
@@ -9,7 +9,11 @@ import { uploadAssets } from "~/shared/db/misc.server";
import { ErrorMessage } from "~/shared/error";
// if this file does not end in .server remix will not build
// since it only allows node code in those files
-import { loadByProject } from "@webstudio-is/asset-uploader/index.server";
+import {
+ deleteAsset,
+ loadByProject,
+} from "@webstudio-is/asset-uploader/index.server";
+import { zfd } from "zod-form-data";
export { links };
@@ -33,19 +37,44 @@ type Error = {
errors: "string";
};
+const deleteAssetSchema = zfd.formData({
+ assetId: zfd.text(),
+ assetName: zfd.text(),
+});
+
export const action: ActionFunction = async ({ request, params }) => {
if (params.id === undefined) throw new Error("Project id undefined");
+ try {
+ if (request.method === "DELETE") {
+ const { assetId, assetName } = deleteAssetSchema.parse(
+ await request.formData()
+ );
+ const deletedAsset = await deleteAsset({
+ id: assetId,
+ name: assetName,
+ });
+
+ return { deletedAsset };
+ }
+ } catch (error) {
+ if (error instanceof Error) {
+ return {
+ errors: error.message,
+ };
+ }
+ }
if (request.method === "POST") {
try {
const assets = await uploadAssets({
request,
projectId: params.id,
- dirname: __dirname,
});
- return assets.map((asset: Asset) => ({
- ...asset,
- status: "uploaded",
- }));
+ return {
+ uploadedAssets: assets.map((asset: Asset) => ({
+ ...asset,
+ status: "uploaded",
+ })),
+ };
} catch (error) {
if (error instanceof Error) {
return {
diff --git a/apps/designer/app/routes/rest/publish.ts b/apps/designer/app/routes/rest/publish.ts
index 04f5bdeb34..29fa2dd5cf 100644
--- a/apps/designer/app/routes/rest/publish.ts
+++ b/apps/designer/app/routes/rest/publish.ts
@@ -1,10 +1,14 @@
import { type ActionFunction } from "@remix-run/node";
+import { zfd } from "zod-form-data";
import * as db from "~/shared/db";
+const schema = zfd.formData({
+ domain: zfd.text(),
+ projectId: zfd.text(),
+});
+
export const action: ActionFunction = async ({ request }) => {
- const formData = await request.formData();
- const domain = formData.get("domain") as string | null;
- const projectId = formData.get("projectId") as string | null;
+ const { domain, projectId } = schema.parse(await request.formData());
try {
const project = await db.misc.publish({ projectId, domain });
return { domain: project.domain };
diff --git a/apps/designer/docs/test-cases.md b/apps/designer/docs/test-cases.md
index b991c78e17..224ee60065 100644
--- a/apps/designer/docs/test-cases.md
+++ b/apps/designer/docs/test-cases.md
@@ -74,3 +74,10 @@
- Add a Box component to the canvas
- Open Props panel
- See the default tag is provided and can be modified
+
+1. Asset manager
+
+ - Open assets panel
+ - Upload an image
+ - Check it loads and shows a progress bar
+ - Delete an asset by clicking on the `x` icon and then the delete button in the tooltip
diff --git a/apps/designer/package.json b/apps/designer/package.json
index 6af3752695..9aca9df4b8 100644
--- a/apps/designer/package.json
+++ b/apps/designer/package.json
@@ -26,8 +26,8 @@
"@stitches/react": "^1.2.7",
"@vercel/node": "^2.4.1",
"@webstudio-is/asset-uploader": "*",
- "@webstudio-is/react-sdk": "*",
"@webstudio-is/prisma-client": "*",
+ "@webstudio-is/react-sdk": "*",
"@webstudio-is/design-system": "*",
"@webstudio-is/icons": "*",
"bson-objectid": "^2.0.2",
@@ -60,7 +60,8 @@
"remix-auth-github": "^1.1.1",
"remix-auth-google": "^1.1.0",
"sharp": "^0.30.7",
- "slugify": "^1.6.5"
+ "slugify": "^1.6.5",
+ "zod-form-data": "^1.2.1"
},
"devDependencies": {
"@babel/core": "^7.18.5",
@@ -98,12 +99,12 @@
"esbuild-jest": "^0.5.0",
"esbuild-node-externals": "^1.4.1",
"esbuild-node-loader": "^0.8.0",
- "eslint-config-custom": "*",
"jest": "^27.5.1",
"prettier": "^2.6.2",
"react-test-renderer": "^17.0.2",
"relative-deps": "^1.0.7",
- "tsconfig": "*",
+ "@webstudio-is/eslint-config-custom": "*",
+ "@webstudio-is/tsconfig": "*",
"typescript": "4.6.4"
},
"sideEffects": false,
diff --git a/apps/designer/tsconfig.json b/apps/designer/tsconfig.json
index fbf716785d..4ce92c95f5 100644
--- a/apps/designer/tsconfig.json
+++ b/apps/designer/tsconfig.json
@@ -1,6 +1,5 @@
{
- // Extends can't use node's resolution rn https://github.com/dividab/tsconfig-paths/issues/209#issuecomment-1177261091
- "extends": "../../node_modules/tsconfig/remix.json",
+ "extends": "../../node_modules/@webstudio-is/tsconfig/remix.json",
"include": ["remix.env.d.ts", "**/*.ts", "**/*.tsx"],
"compilerOptions": {
"paths": {
diff --git a/package.json b/package.json
index 504f3f4a01..cbcd14529f 100644
--- a/package.json
+++ b/package.json
@@ -17,7 +17,7 @@
"storybook": "turbo run storybook:run"
},
"devDependencies": {
- "eslint-config-custom": "*",
+ "@webstudio-is/eslint-config-custom": "*",
"husky": ">=6",
"lint-staged": "^13.0.2",
"prettier": "latest",
diff --git a/packages/asset-uploader/jest.config.js b/packages/asset-uploader/jest.config.js
index 03c0db11ea..9eae0843c6 100644
--- a/packages/asset-uploader/jest.config.js
+++ b/packages/asset-uploader/jest.config.js
@@ -1,5 +1,5 @@
// eslint-disable-next-line
-const base = require("jest-config/jest.config.js");
+const base = require("@webstudio-is/jest-config");
module.exports = {
...base,
diff --git a/packages/asset-uploader/package.json b/packages/asset-uploader/package.json
index cbef3f028d..875be06eba 100644
--- a/packages/asset-uploader/package.json
+++ b/packages/asset-uploader/package.json
@@ -15,13 +15,15 @@
"dependencies": {
"@aws-sdk/client-s3": "^3.131.0",
"@aws-sdk/lib-storage": "^3.131.0",
- "sharp": "^0.30.7",
- "@webstudio-is/prisma-client": "*"
+ "@webstudio-is/prisma-client": "*",
+ "app-root-path": "^3.0.0",
+ "sharp": "^0.30.7"
},
"devDependencies": {
+ "@types/app-root-path": "^1.2.4",
"@types/node": "^17.0.21",
"@types/sharp": "^0.30.4",
- "jest-config": "*",
+ "@webstudio-is/jest-config": "*",
"tsup": "^6.1.3",
"typescript": "^4.6.2",
"zod": "^3.17.3"
diff --git a/packages/asset-uploader/src/constants.ts b/packages/asset-uploader/src/constants.ts
index 6750073003..6616fc8004 100644
--- a/packages/asset-uploader/src/constants.ts
+++ b/packages/asset-uploader/src/constants.ts
@@ -1 +1 @@
-export const DEFAULT_UPLPOAD_PATH = "uploads";
+export const DEFAULT_UPLOAD_PATH = "public/uploads";
diff --git a/packages/asset-uploader/src/db/delete.ts b/packages/asset-uploader/src/db/delete.ts
new file mode 100644
index 0000000000..9898fbe420
--- /dev/null
+++ b/packages/asset-uploader/src/db/delete.ts
@@ -0,0 +1,12 @@
+import { prisma, Asset } from "@webstudio-is/prisma-client";
+import { getAssetPath } from "../helpers/get-asset-path";
+
+export const deleteAssetInDb = async (assetId: Asset["id"]): Promise => {
+ if (typeof assetId !== "string") {
+ throw new Error("Asset ID required");
+ }
+
+ const removedAsset = await prisma.asset.delete({ where: { id: assetId } });
+
+ return { ...removedAsset, path: getAssetPath(removedAsset) };
+};
diff --git a/packages/asset-uploader/src/db/index.ts b/packages/asset-uploader/src/db/index.ts
index 52122ec551..7a4923ced3 100644
--- a/packages/asset-uploader/src/db/index.ts
+++ b/packages/asset-uploader/src/db/index.ts
@@ -1,2 +1,3 @@
export * from "./create";
export * from "./load";
+export * from "./delete";
diff --git a/packages/asset-uploader/src/db/load.ts b/packages/asset-uploader/src/db/load.ts
index 25cfa43872..9fde8948d2 100644
--- a/packages/asset-uploader/src/db/load.ts
+++ b/packages/asset-uploader/src/db/load.ts
@@ -5,7 +5,7 @@ export const loadByProject = async (
projectId?: Project["id"]
): Promise => {
if (typeof projectId !== "string") {
- throw new Error("Tree ID required");
+ throw new Error("Project ID required");
}
const assets = await prisma.asset.findMany({
diff --git a/packages/asset-uploader/src/delete.ts b/packages/asset-uploader/src/delete.ts
new file mode 100644
index 0000000000..b53930a09d
--- /dev/null
+++ b/packages/asset-uploader/src/delete.ts
@@ -0,0 +1,38 @@
+import { DeleteObjectCommand } from "@aws-sdk/client-s3";
+import { prisma, Asset } from "@webstudio-is/prisma-client";
+import { unlink } from "fs/promises";
+import path from "path";
+import { deleteAssetInDb } from "./db";
+import { imageFsDirectory } from "./helpers/image-fs-path";
+import { s3EnvVariables } from "./schema";
+import { getS3Client } from "./targets/s3/client";
+
+export const deleteAsset = async ({
+ id,
+ name,
+}: {
+ id: string;
+ name: string;
+}): Promise => {
+ const currentAsset = await prisma.asset.findUnique({
+ where: { id },
+ });
+ if (!currentAsset) throw new Error("Asset does not exist");
+
+ if (currentAsset.location === "REMOTE") {
+ const s3Envs = s3EnvVariables.parse(process.env);
+ await getS3Client().send(
+ new DeleteObjectCommand({
+ Bucket: s3Envs.S3_BUCKET,
+ Key: name,
+ })
+ );
+
+ return await deleteAssetInDb(id);
+ } else {
+ const directory = await imageFsDirectory();
+ await unlink(path.join(directory, name));
+
+ return await deleteAssetInDb(id);
+ }
+};
diff --git a/packages/asset-uploader/src/helpers/get-asset-path.ts b/packages/asset-uploader/src/helpers/get-asset-path.ts
index 168fdc6c52..1403f9790b 100644
--- a/packages/asset-uploader/src/helpers/get-asset-path.ts
+++ b/packages/asset-uploader/src/helpers/get-asset-path.ts
@@ -7,7 +7,8 @@ const fsEnvs = fsEnvVariables.parse(process.env);
export const getAssetPath = (asset: DbAsset) => {
if (asset.location === Location.FS) {
- return path.join("/", fsEnvs.FILE_UPLOAD_PATH, asset.name);
+ const splitPath = fsEnvs.FILE_UPLOAD_PATH.split("public");
+ return path.join("/", splitPath[splitPath.length - 1], asset.name);
}
if (asset.location === Location.REMOTE && s3Envs.success) {
diff --git a/packages/asset-uploader/src/helpers/image-fs-path.ts b/packages/asset-uploader/src/helpers/image-fs-path.ts
new file mode 100644
index 0000000000..6889eb1d61
--- /dev/null
+++ b/packages/asset-uploader/src/helpers/image-fs-path.ts
@@ -0,0 +1,17 @@
+import path from "path";
+import appRoot from "app-root-path";
+import { fsEnvVariables } from "../schema";
+const fsUploadVars = fsEnvVariables.parse(process.env);
+
+export const imageFsDirectory = () => {
+ const isProd = process.env.NODE_ENV === "production";
+
+ if (isProd) return path.join(appRoot.path, fsUploadVars.FILE_UPLOAD_PATH);
+
+ return path.join(
+ appRoot.path,
+ "apps",
+ "designer",
+ fsUploadVars.FILE_UPLOAD_PATH
+ );
+};
diff --git a/packages/asset-uploader/src/index.ts b/packages/asset-uploader/src/index.ts
index 22321d4d77..25948908ae 100644
--- a/packages/asset-uploader/src/index.ts
+++ b/packages/asset-uploader/src/index.ts
@@ -1,2 +1,3 @@
export * from "./upload";
+export * from "./delete";
export * from "./db";
diff --git a/packages/asset-uploader/src/schema.ts b/packages/asset-uploader/src/schema.ts
index 45399df529..12205c9724 100644
--- a/packages/asset-uploader/src/schema.ts
+++ b/packages/asset-uploader/src/schema.ts
@@ -1,6 +1,6 @@
import { z } from "zod";
import { NodeOnDiskFile } from "@remix-run/node";
-import { DEFAULT_UPLPOAD_PATH } from "./constants";
+import { DEFAULT_UPLOAD_PATH } from "./constants";
const SingleImageInUpload = z.instanceof(NodeOnDiskFile);
@@ -25,7 +25,7 @@ export const s3EnvVariables = z.object({
});
export const fsEnvVariables = z.object({
- FILE_UPLOAD_PATH: z.string().optional().default(DEFAULT_UPLPOAD_PATH),
+ FILE_UPLOAD_PATH: z.string().optional().default(DEFAULT_UPLOAD_PATH),
});
export const assetEnvVariables = z.object({
diff --git a/packages/asset-uploader/src/targets/s3/client.ts b/packages/asset-uploader/src/targets/s3/client.ts
new file mode 100644
index 0000000000..0532597bcb
--- /dev/null
+++ b/packages/asset-uploader/src/targets/s3/client.ts
@@ -0,0 +1,14 @@
+import { S3Client } from "@aws-sdk/client-s3";
+import { s3EnvVariables } from "../../schema";
+
+export const getS3Client = () => {
+ const s3Envs = s3EnvVariables.parse(process.env);
+ return new S3Client({
+ endpoint: s3Envs.S3_ENDPOINT,
+ region: s3Envs.S3_REGION,
+ credentials: {
+ accessKeyId: s3Envs.S3_ACCESS_KEY_ID,
+ secretAccessKey: s3Envs.S3_SECRET_ACCESS_KEY,
+ },
+ });
+};
diff --git a/packages/asset-uploader/src/targets/s3/handler.ts b/packages/asset-uploader/src/targets/s3/handler.ts
index a2573ff9c1..24440b0050 100644
--- a/packages/asset-uploader/src/targets/s3/handler.ts
+++ b/packages/asset-uploader/src/targets/s3/handler.ts
@@ -1,5 +1,5 @@
import { UploadHandlerPart } from "@remix-run/node";
-import { PutObjectCommandInput, S3Client } from "@aws-sdk/client-s3";
+import { PutObjectCommandInput } from "@aws-sdk/client-s3";
import { Upload } from "@aws-sdk/lib-storage";
import ObjectID from "bson-objectid";
@@ -14,6 +14,7 @@ import {
getFilenameAndExtension,
} from "../../helpers/array-buffer-helpers";
import { Location } from "@webstudio-is/prisma-client";
+import { getS3Client } from "./client";
type S3UploadHandler = ({
file,
@@ -57,16 +58,7 @@ export const s3UploadHandler: S3UploadHandler = async ({
},
};
- const client = new S3Client({
- endpoint: s3Envs.S3_ENDPOINT,
- region: s3Envs.S3_REGION,
- credentials: {
- accessKeyId: s3Envs.S3_ACCESS_KEY_ID,
- secretAccessKey: s3Envs.S3_SECRET_ACCESS_KEY,
- },
- });
-
- const upload = new Upload({ client, params });
+ const upload = new Upload({ client: getS3Client(), params });
ImagesUploadedSuccess.parse(await upload.done());
const image = sharp(uint8Array);
diff --git a/packages/asset-uploader/src/upload.ts b/packages/asset-uploader/src/upload.ts
index 34fcf6075e..cd1c26af61 100644
--- a/packages/asset-uploader/src/upload.ts
+++ b/packages/asset-uploader/src/upload.ts
@@ -1,4 +1,3 @@
-import path from "path";
import {
unstable_createFileUploadHandler,
unstable_parseMultipartFormData,
@@ -6,10 +5,12 @@ import {
import { s3UploadHandler } from "./targets/s3/handler";
import { uploadToS3 } from "./targets/s3/uploader";
import { uploadToDisk } from "./targets/disk/upload";
-import { assetEnvVariables, fsEnvVariables, s3EnvVariables } from "./schema";
+import { assetEnvVariables, s3EnvVariables } from "./schema";
+import { Asset } from "@webstudio-is/prisma-client";
+import { imageFsDirectory } from "./helpers/image-fs-path";
const isS3Upload = s3EnvVariables.safeParse(process.env).success;
-const fsUploadVars = fsEnvVariables.parse(process.env);
+
const commonUploadVars = assetEnvVariables.parse(process.env);
// user inputs the max value in mb and we transform it to bytes
@@ -18,14 +19,11 @@ export const MAX_UPLOAD_SIZE = parseInt(commonUploadVars.MAX_UPLOAD_SIZE) * 1e6;
export const uploadAssets = async ({
request,
projectId,
- dirname,
}: {
request: Request;
projectId: string;
- dirname: string;
-}) => {
- const uploads = path.join(dirname, "../public");
- const directory = path.join(uploads, fsUploadVars.FILE_UPLOAD_PATH);
+}): Promise => {
+ const directory = await imageFsDirectory();
const formData = await unstable_parseMultipartFormData(
request,
isS3Upload
diff --git a/packages/asset-uploader/tsconfig.json b/packages/asset-uploader/tsconfig.json
index fe21c2ae7b..654f479a30 100644
--- a/packages/asset-uploader/tsconfig.json
+++ b/packages/asset-uploader/tsconfig.json
@@ -1,6 +1,6 @@
// Extends can't use node's resolution rn https://github.com/dividab/tsconfig-paths/issues/209#issuecomment-1177261091
{
- "extends": "../../node_modules/tsconfig/base.json",
+ "extends": "../../node_modules/@webstudio-is/tsconfig/base.json",
"include": ["./src/**/*.ts"],
"compilerOptions": {
"module": "commonjs",
diff --git a/packages/design-system/package.json b/packages/design-system/package.json
index 1b32378017..d181546931 100644
--- a/packages/design-system/package.json
+++ b/packages/design-system/package.json
@@ -55,9 +55,10 @@
"@radix-ui/react-tabs": "^0.1.5",
"@radix-ui/react-toggle": "^0.1.4",
"@radix-ui/react-toggle-group": "^0.1.5",
- "@radix-ui/react-tooltip": "^0.1.7",
+ "@radix-ui/react-tooltip": "^1.0.0",
"@radix-ui/react-use-layout-effect": "^0.1.0",
- "@webstudio-is/icons": "*"
+ "@webstudio-is/icons": "*",
+ "@webstudio-is/react-sdk": "*"
},
"main": "lib/index.js",
"types": "lib/index.d.ts",
diff --git a/packages/design-system/src/components/tooltip.tsx b/packages/design-system/src/components/tooltip.tsx
index 5eee96c9f7..0cb9d347ee 100644
--- a/packages/design-system/src/components/tooltip.tsx
+++ b/packages/design-system/src/components/tooltip.tsx
@@ -1,8 +1,9 @@
-import React from "react";
+import React, { Ref } from "react";
import { styled } from "../stitches.config";
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
import { Box } from "./box";
import { Text } from "./text";
+import type { CSS } from "@webstudio-is/react-sdk";
type TooltipProps = React.ComponentProps &
React.ComponentProps & {
@@ -10,6 +11,7 @@ type TooltipProps = React.ComponentProps &
content: React.ReactNode;
multiline?: boolean;
delayDuration?: number;
+ css?: CSS;
};
const Content = styled(TooltipPrimitive.Content, {
@@ -18,27 +20,40 @@ const Content = styled(TooltipPrimitive.Content, {
color: "$hiContrast",
borderRadius: "$1",
padding: "$1 $2",
+ zIndex: "$max",
+ position: "relative",
variants: {
multiline: {
true: {
- maxWidth: 250,
+ // @todo makew this part of the design system
+ maxWidth: 110,
pb: 7,
},
},
},
});
-export const Tooltip = ({
- children,
- content,
- open,
- defaultOpen,
- onOpenChange,
- multiline,
- delayDuration,
- ...props
-}: TooltipProps) => {
+const Arrow = styled(TooltipPrimitive.Arrow, {
+ fill: "$loContrast",
+ stroke: "$slate7",
+ strokeWidth: "$1",
+ marginTop: -0.5,
+});
+
+export const Tooltip = React.forwardRef(function TooltipWrapper(
+ {
+ children,
+ content,
+ open,
+ defaultOpen,
+ onOpenChange,
+ multiline,
+ delayDuration,
+ ...props
+ }: TooltipProps,
+ ref: Ref
+) {
return (
{children}
-
+
);
-};
+});
diff --git a/packages/design-system/tsconfig.json b/packages/design-system/tsconfig.json
index 329cf3ea13..e599e806b6 100644
--- a/packages/design-system/tsconfig.json
+++ b/packages/design-system/tsconfig.json
@@ -1,6 +1,6 @@
// Extends can't use node's resolution rn https://github.com/dividab/tsconfig-paths/issues/209#issuecomment-1177261091
{
- "extends": "../../node_modules/tsconfig/base.json",
+ "extends": "../../node_modules/@webstudio-is/tsconfig/base.json",
"include": ["./src/**/*.ts", "./src/**/*.tsx"],
"compilerOptions": {
"lib": ["DOM", "DOM.Iterable", "ES2019"],
diff --git a/packages/eslint-config-custom/package.json b/packages/eslint-config-custom/package.json
index 158b766152..30efd8e4c4 100644
--- a/packages/eslint-config-custom/package.json
+++ b/packages/eslint-config-custom/package.json
@@ -1,6 +1,6 @@
{
- "name": "eslint-config-custom",
- "version": "0.0.0",
+ "name": "@webstudio-is/eslint-config-custom",
+ "version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
diff --git a/packages/icons/package.json b/packages/icons/package.json
index b764e507ef..69a6fb16c7 100644
--- a/packages/icons/package.json
+++ b/packages/icons/package.json
@@ -1,7 +1,7 @@
{
"name": "@webstudio-is/icons",
- "version": "0.5.0",
- "description": "Webstudio JavaScript / TypeScript API",
+ "version": "0.1.0",
+ "description": "Webstudio Icons",
"author": "Webstudio ",
"homepage": "https://webstudio.is",
"scripts": {
diff --git a/packages/icons/tsconfig.json b/packages/icons/tsconfig.json
index 329cf3ea13..e599e806b6 100644
--- a/packages/icons/tsconfig.json
+++ b/packages/icons/tsconfig.json
@@ -1,6 +1,6 @@
// Extends can't use node's resolution rn https://github.com/dividab/tsconfig-paths/issues/209#issuecomment-1177261091
{
- "extends": "../../node_modules/tsconfig/base.json",
+ "extends": "../../node_modules/@webstudio-is/tsconfig/base.json",
"include": ["./src/**/*.ts", "./src/**/*.tsx"],
"compilerOptions": {
"lib": ["DOM", "DOM.Iterable", "ES2019"],
diff --git a/packages/jest-config/jest.config.js b/packages/jest-config/index.js
similarity index 100%
rename from packages/jest-config/jest.config.js
rename to packages/jest-config/index.js
diff --git a/packages/jest-config/package.json b/packages/jest-config/package.json
index ef615bcf82..001d6d9a39 100644
--- a/packages/jest-config/package.json
+++ b/packages/jest-config/package.json
@@ -1,6 +1,6 @@
{
- "name": "jest-config",
- "version": "0.0.0",
+ "name": "@webstudio-is/jest-config",
+ "version": "1.0.1",
"license": "MIT",
"dependencies": {
"@types/jest": "^27.4.1",
diff --git a/packages/prisma-client/tsconfig.json b/packages/prisma-client/tsconfig.json
index e895781976..ff828da22f 100644
--- a/packages/prisma-client/tsconfig.json
+++ b/packages/prisma-client/tsconfig.json
@@ -1,6 +1,6 @@
// Extends can't use node's resolution rn https://github.com/dividab/tsconfig-paths/issues/209#issuecomment-1177261091
{
- "extends": "../../node_modules/tsconfig/base.json",
+ "extends": "../../node_modules/@webstudio-is/tsconfig/base.json",
"include": ["./src/**/*.ts"],
"compilerOptions": {
"module": "commonjs",
diff --git a/packages/react-sdk/jest.config.js b/packages/react-sdk/jest.config.js
index 03c0db11ea..9eae0843c6 100644
--- a/packages/react-sdk/jest.config.js
+++ b/packages/react-sdk/jest.config.js
@@ -1,5 +1,5 @@
// eslint-disable-next-line
-const base = require("jest-config/jest.config.js");
+const base = require("@webstudio-is/jest-config");
module.exports = {
...base,
diff --git a/packages/react-sdk/package.json b/packages/react-sdk/package.json
index 3b6256d555..5bf5020e21 100644
--- a/packages/react-sdk/package.json
+++ b/packages/react-sdk/package.json
@@ -33,18 +33,18 @@
"@types/css-tree": "^1.0.7",
"@types/fs-extra": "^9.0.13",
"@types/node": "^17.0.21",
- "@webstudio-is/prisma-client": "*",
"babel-loader": "^8.2.5",
"camelcase": "^6.3.0",
"css-tree": "^2.1.0",
"esbuild": "^0.14.25",
"esbuild-node-externals": "^1.4.1",
"esbuild-node-loader": "^0.8.0",
- "jest-config": "*",
+ "@webstudio-is/jest-config": "*",
"mdn-data": "2.0.23",
"react": "^17.0.2",
"react-docgen-typescript": "^2.2.2",
"react-dom": "^17.0.2",
+ "@webstudio-is/prisma-client": "*",
"tsup": "^6.1.3",
"typescript": "^4.6.2"
},
@@ -59,9 +59,9 @@
"@stitches/core": "^1.2.7",
"@webstudio-is/icons": "*",
"immer": "^9.0.12",
- "jest-config": "*",
"mitt": "^3.0.0",
"react-nano-state": "^0.4.0",
+ "@webstudio-is/jest-config": "*",
"zod": "^3.17.3"
},
"main": "lib/index.js",
diff --git a/packages/react-sdk/tsconfig.json b/packages/react-sdk/tsconfig.json
index 329cf3ea13..e599e806b6 100644
--- a/packages/react-sdk/tsconfig.json
+++ b/packages/react-sdk/tsconfig.json
@@ -1,6 +1,6 @@
// Extends can't use node's resolution rn https://github.com/dividab/tsconfig-paths/issues/209#issuecomment-1177261091
{
- "extends": "../../node_modules/tsconfig/base.json",
+ "extends": "../../node_modules/@webstudio-is/tsconfig/base.json",
"include": ["./src/**/*.ts", "./src/**/*.tsx"],
"compilerOptions": {
"lib": ["DOM", "DOM.Iterable", "ES2019"],
diff --git a/packages/tsconfig/package.json b/packages/tsconfig/package.json
index a32fc41922..56f2bd444d 100644
--- a/packages/tsconfig/package.json
+++ b/packages/tsconfig/package.json
@@ -1,7 +1,7 @@
{
- "name": "tsconfig",
- "version": "0.0.0",
- "private": true,
+ "name": "@webstudio-is/tsconfig",
+ "version": "1.0.0",
+ "private": false,
"main": "index.js",
"files": [
"base.json",
diff --git a/yarn.lock b/yarn.lock
index fd8230baa8..38b02e8583 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2752,6 +2752,13 @@
dependencies:
"@babel/runtime" "^7.13.10"
+"@radix-ui/primitive@1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.0.0.tgz#e1d8ef30b10ea10e69c76e896f608d9276352253"
+ integrity sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==
+ dependencies:
+ "@babel/runtime" "^7.13.10"
+
"@radix-ui/react-accessible-icon@^0.1.4":
version "0.1.4"
resolved "https://registry.yarnpkg.com/@radix-ui/react-accessible-icon/-/react-accessible-icon-0.1.4.tgz#bdbf1e3226a0e9e7778b68728b175bdc532b720c"
@@ -2931,6 +2938,18 @@
"@radix-ui/react-use-callback-ref" "0.1.0"
"@radix-ui/react-use-escape-keydown" "0.1.0"
+"@radix-ui/react-dismissable-layer@1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.0.tgz#35b7826fa262fd84370faef310e627161dffa76b"
+ integrity sha512-n7kDRfx+LB1zLueRDvZ1Pd0bxdJWDUZNQ/GWoxDn2prnuJKRdxsjulejX/ePkOsLi2tTm6P24mDqlMSgQpsT6g==
+ dependencies:
+ "@babel/runtime" "^7.13.10"
+ "@radix-ui/primitive" "1.0.0"
+ "@radix-ui/react-compose-refs" "1.0.0"
+ "@radix-ui/react-primitive" "1.0.0"
+ "@radix-ui/react-use-callback-ref" "1.0.0"
+ "@radix-ui/react-use-escape-keydown" "1.0.0"
+
"@radix-ui/react-dropdown-menu@^0.1.6":
version "0.1.6"
resolved "https://registry.yarnpkg.com/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-0.1.6.tgz#3203229788cd57e552c9f19dcc7008e2b545919c"
@@ -2975,6 +2994,14 @@
"@babel/runtime" "^7.13.10"
"@radix-ui/react-use-layout-effect" "0.1.0"
+"@radix-ui/react-id@1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.0.0.tgz#8d43224910741870a45a8c9d092f25887bb6d11e"
+ integrity sha512-Q6iAB/U7Tq3NTolBBQbHTgclPmGWE3OlktGGqrClPozSw4vkQ1DfQAOtzgRPecKsMdJINE05iaoDUG8tRzCBjw==
+ dependencies:
+ "@babel/runtime" "^7.13.10"
+ "@radix-ui/react-use-layout-effect" "1.0.0"
+
"@radix-ui/react-label@0.1.5", "@radix-ui/react-label@^0.1.5":
version "0.1.5"
resolved "https://registry.yarnpkg.com/@radix-ui/react-label/-/react-label-0.1.5.tgz#12cd965bfc983e0148121d4c99fb8e27a917c45c"
@@ -3046,7 +3073,7 @@
"@radix-ui/react-use-size" "0.1.1"
"@radix-ui/rect" "0.1.1"
-"@radix-ui/react-popper@^1.0.0":
+"@radix-ui/react-popper@1.0.0", "@radix-ui/react-popper@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@radix-ui/react-popper/-/react-popper-1.0.0.tgz#fb4f937864bf39c48f27f55beee61fa9f2bef93c"
integrity sha512-k2dDd+1Wl0XWAMs9ZvAxxYsB9sOsEhrFQV4CINd7IUZf0wfdye4OHen9siwxvZImbzhgVeKTJi68OQmPRvVdMg==
@@ -3071,6 +3098,14 @@
"@radix-ui/react-primitive" "0.1.4"
"@radix-ui/react-use-layout-effect" "0.1.0"
+"@radix-ui/react-portal@1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.0.0.tgz#7220b66743394fabb50c55cb32381395cc4a276b"
+ integrity sha512-a8qyFO/Xb99d8wQdu4o7qnigNjTPG123uADNecz0eX4usnQEj7o+cG4ZX4zkqq98NYekT7UoEQIjxBNWIFuqTA==
+ dependencies:
+ "@babel/runtime" "^7.13.10"
+ "@radix-ui/react-primitive" "1.0.0"
+
"@radix-ui/react-presence@0.1.2":
version "0.1.2"
resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-0.1.2.tgz#9f11cce3df73cf65bc348e8b76d891f0d54c1fe3"
@@ -3080,6 +3115,15 @@
"@radix-ui/react-compose-refs" "0.1.0"
"@radix-ui/react-use-layout-effect" "0.1.0"
+"@radix-ui/react-presence@1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.0.0.tgz#814fe46df11f9a468808a6010e3f3ca7e0b2e84a"
+ integrity sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w==
+ dependencies:
+ "@babel/runtime" "^7.13.10"
+ "@radix-ui/react-compose-refs" "1.0.0"
+ "@radix-ui/react-use-layout-effect" "1.0.0"
+
"@radix-ui/react-primitive@0.1.4":
version "0.1.4"
resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-0.1.4.tgz#6c233cf08b0cb87fecd107e9efecb3f21861edc1"
@@ -3255,26 +3299,24 @@
"@radix-ui/react-primitive" "0.1.4"
"@radix-ui/react-use-controllable-state" "0.1.0"
-"@radix-ui/react-tooltip@^0.1.7":
- version "0.1.7"
- resolved "https://registry.yarnpkg.com/@radix-ui/react-tooltip/-/react-tooltip-0.1.7.tgz#6f8c00d6e489565d14abf209ce0fb8853c8c8ee3"
- integrity sha512-eiBUsVOHenZ0JR16tl970bB0DafJBz6mFgSGfIGIVpflFj0LIsIDiLMsYyvYdx1KwwsIUDTEZtxcPm/sWjPzqA==
+"@radix-ui/react-tooltip@^1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@radix-ui/react-tooltip/-/react-tooltip-1.0.0.tgz#f7fcecf2bac5c31cd14666b5acd056015fc21646"
+ integrity sha512-RB06pov+O4Npy10ei1C6fsyB9QoOjz7Ubo8Sl3qdKtLgkL9iI96925DYtH0bxx6MH6YB2FuzLU6B75qn3AQQQw==
dependencies:
"@babel/runtime" "^7.13.10"
- "@radix-ui/primitive" "0.1.0"
- "@radix-ui/react-compose-refs" "0.1.0"
- "@radix-ui/react-context" "0.1.1"
- "@radix-ui/react-id" "0.1.5"
- "@radix-ui/react-popper" "0.1.4"
- "@radix-ui/react-portal" "0.1.4"
- "@radix-ui/react-presence" "0.1.2"
- "@radix-ui/react-primitive" "0.1.4"
- "@radix-ui/react-slot" "0.1.2"
- "@radix-ui/react-use-controllable-state" "0.1.0"
- "@radix-ui/react-use-escape-keydown" "0.1.0"
- "@radix-ui/react-use-previous" "0.1.1"
- "@radix-ui/react-use-rect" "0.1.1"
- "@radix-ui/react-visually-hidden" "0.1.4"
+ "@radix-ui/primitive" "1.0.0"
+ "@radix-ui/react-compose-refs" "1.0.0"
+ "@radix-ui/react-context" "1.0.0"
+ "@radix-ui/react-dismissable-layer" "1.0.0"
+ "@radix-ui/react-id" "1.0.0"
+ "@radix-ui/react-popper" "1.0.0"
+ "@radix-ui/react-portal" "1.0.0"
+ "@radix-ui/react-presence" "1.0.0"
+ "@radix-ui/react-primitive" "1.0.0"
+ "@radix-ui/react-slot" "1.0.0"
+ "@radix-ui/react-use-controllable-state" "1.0.0"
+ "@radix-ui/react-visually-hidden" "1.0.0"
"@radix-ui/react-use-body-pointer-events@0.1.1":
version "0.1.1"
@@ -3291,6 +3333,13 @@
dependencies:
"@babel/runtime" "^7.13.10"
+"@radix-ui/react-use-callback-ref@1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.0.tgz#9e7b8b6b4946fe3cbe8f748c82a2cce54e7b6a90"
+ integrity sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg==
+ dependencies:
+ "@babel/runtime" "^7.13.10"
+
"@radix-ui/react-use-controllable-state@0.1.0":
version "0.1.0"
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-0.1.0.tgz#4fced164acfc69a4e34fb9d193afdab973a55de1"
@@ -3299,6 +3348,14 @@
"@babel/runtime" "^7.13.10"
"@radix-ui/react-use-callback-ref" "0.1.0"
+"@radix-ui/react-use-controllable-state@1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.0.tgz#a64deaafbbc52d5d407afaa22d493d687c538b7f"
+ integrity sha512-FohDoZvk3mEXh9AWAVyRTYR4Sq7/gavuofglmiXB2g1aKyboUD4YtgWxKj8O5n+Uak52gXQ4wKz5IFST4vtJHg==
+ dependencies:
+ "@babel/runtime" "^7.13.10"
+ "@radix-ui/react-use-callback-ref" "1.0.0"
+
"@radix-ui/react-use-direction@0.1.0":
version "0.1.0"
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-direction/-/react-use-direction-0.1.0.tgz#97ac1d52e497c974389e7988f809238ed72e7df7"
@@ -3314,6 +3371,14 @@
"@babel/runtime" "^7.13.10"
"@radix-ui/react-use-callback-ref" "0.1.0"
+"@radix-ui/react-use-escape-keydown@1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.0.tgz#aef375db4736b9de38a5a679f6f49b45a060e5d1"
+ integrity sha512-JwfBCUIfhXRxKExgIqGa4CQsiMemo1Xt0W/B4ei3fpzpvPENKpMKQ8mZSB6Acj3ebrAEgi2xiQvcI1PAAodvyg==
+ dependencies:
+ "@babel/runtime" "^7.13.10"
+ "@radix-ui/react-use-callback-ref" "1.0.0"
+
"@radix-ui/react-use-layout-effect@0.1.0", "@radix-ui/react-use-layout-effect@^0.1.0":
version "0.1.0"
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-0.1.0.tgz#ebf71bd6d2825de8f1fbb984abf2293823f0f223"
@@ -3374,6 +3439,14 @@
"@babel/runtime" "^7.13.10"
"@radix-ui/react-primitive" "0.1.4"
+"@radix-ui/react-visually-hidden@1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.0.tgz#4d69d7e3b6d21ee4678ed6de5215dcd068394401"
+ integrity sha512-MwAhMdX+n6S4InwRKSnpUsp+lLkYG6izQF56ul6guSX2mBBLOMV9Frx7xJlkEe2GjKLzbNuHhaCS6e5gopmZNA==
+ dependencies:
+ "@babel/runtime" "^7.13.10"
+ "@radix-ui/react-primitive" "1.0.0"
+
"@radix-ui/rect@0.1.1":
version "0.1.1"
resolved "https://registry.yarnpkg.com/@radix-ui/rect/-/rect-0.1.1.tgz#95b5ba51f469bea6b1b841e2d427e17e37d38419"
@@ -4762,6 +4835,11 @@
dependencies:
"@types/estree" "*"
+"@types/app-root-path@^1.2.4":
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/@types/app-root-path/-/app-root-path-1.2.4.tgz#a78b703282b32ac54de768f5512ecc3569919dc7"
+ integrity sha512-yhURoXmWN/zfw2MXXcOdUTwe5CWhzRWtb4Rs2+JwGpuhm2hxLCzjASi/aIuyVeJB3Iyks1teaHyOEfNNmltdvQ==
+
"@types/aria-query@^4.2.0":
version "4.2.2"
resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.2.tgz#ed4e0ad92306a704f9fb132a0cfcf77486dbe2bc"
@@ -5893,6 +5971,11 @@ app-root-dir@^1.0.2:
resolved "https://registry.yarnpkg.com/app-root-dir/-/app-root-dir-1.0.2.tgz#38187ec2dea7577fff033ffcb12172692ff6e118"
integrity sha512-jlpIfsOoNoafl92Sz//64uQHGSyMrD2vYG5d8o2a4qGvyNCvXur7bzIsWtAC/6flI2RYAp3kv8rsfBtaLm7w0g==
+app-root-path@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-3.0.0.tgz#210b6f43873227e18a4b810a032283311555d5ad"
+ integrity sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw==
+
aproba@^1.0.3, aproba@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
@@ -17918,6 +18001,11 @@ yocto-queue@^0.1.0:
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
+zod-form-data@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/zod-form-data/-/zod-form-data-1.2.1.tgz#6da07d7964765b464e959a75f0d797690ee477f7"
+ integrity sha512-L4zocmlzikYB9A2uVVj3OUKX/t3spOZTzQLOhoCXECn9w+eN3bw0D/KYGX4J72iLdCIwDP6YJyYwVXkx3WTu7A==
+
zod@^3.17.3:
version "3.17.3"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.17.3.tgz#86abbc670ff0063a4588d85a4dcc917d6e4af2ba"