diff --git a/apps/designer/app/designer/features/sidebar-left/panels/asset-manager/add-an-asset-form.tsx b/apps/designer/app/designer/features/sidebar-left/panels/asset-manager/add-an-asset-form.tsx index eecaa51ab3..9162174d4f 100644 --- a/apps/designer/app/designer/features/sidebar-left/panels/asset-manager/add-an-asset-form.tsx +++ b/apps/designer/app/designer/features/sidebar-left/panels/asset-manager/add-an-asset-form.tsx @@ -1,8 +1,9 @@ import { Form, useSubmit } from "@remix-run/react"; import ObjectID from "bson-objectid"; import { ChangeEvent, useRef } from "react"; -import { Button } from "@webstudio-is/design-system"; +import { Button, Flex, Text } from "@webstudio-is/design-system"; import { BaseAsset } from "./types"; +import { UploadIcon } from "@webstudio-is/icons"; const readImages = async (fileList: FileList): Promise => { const images = []; @@ -61,8 +62,12 @@ export const AddAnAssetForm = ({ variant="blue" type="button" onClick={() => inputRef?.current?.click()} + size={2} > - Upload Image + + + Upload + ); diff --git a/apps/designer/app/designer/features/sidebar-left/panels/asset-manager/asset-tooltip.tsx b/apps/designer/app/designer/features/sidebar-left/panels/asset-manager/asset-info-tigger.tsx similarity index 67% rename from apps/designer/app/designer/features/sidebar-left/panels/asset-manager/asset-tooltip.tsx rename to apps/designer/app/designer/features/sidebar-left/panels/asset-manager/asset-info-tigger.tsx index 84d57de838..296db6a2ed 100644 --- a/apps/designer/app/designer/features/sidebar-left/panels/asset-manager/asset-tooltip.tsx +++ b/apps/designer/app/designer/features/sidebar-left/panels/asset-manager/asset-info-tigger.tsx @@ -1,12 +1,19 @@ import { useState } from "react"; import { Button, Tooltip } from "@webstudio-is/design-system"; -import { GearIcon } from "@webstudio-is/icons"; +import { GearIcon, gearIconCssVars } from "@webstudio-is/icons"; import { AssetInfo } from "./asset-info"; import { PANEL_WIDTH } from "~/designer/shared/constants"; +import { cssVars } from "@webstudio-is/css-vars"; import { BaseAsset } from "./types"; -export const AssetTooltip = ({ +const triggerVisibilityVar = cssVars.define("trigger-visibility"); + +export const assetInfoTriggerCssVars = ({ show }: { show: boolean }) => ({ + [triggerVisibilityVar]: show ? "visible" : "hidden", +}); + +export const AssetInfoTrigger = ({ asset, onDelete, }: { @@ -15,7 +22,6 @@ export const AssetTooltip = ({ }) => { const [isTooltipOpen, setTooltipOpen] = useState(false); const closeTooltip = () => setTooltipOpen(false); - return ( setTooltipOpen(true)} css={{ - opacity: 0, + visibility: cssVars.use(triggerVisibilityVar, "hidden"), position: "absolute", + color: "$slate11", top: "$1", right: "$1", cursor: "pointer", - color: "$hiContrast", transition: "opacity 100ms ease", + "&:hover": { + color: "$hiContrast", + }, + ...gearIconCssVars({ fill: "$colors$loContrast" }), }} > diff --git a/apps/designer/app/designer/features/sidebar-left/panels/asset-manager/asset-manager.tsx b/apps/designer/app/designer/features/sidebar-left/panels/asset-manager/asset-manager.tsx index f702b666ca..4eedaa2acd 100644 --- a/apps/designer/app/designer/features/sidebar-left/panels/asset-manager/asset-manager.tsx +++ b/apps/designer/app/designer/features/sidebar-left/panels/asset-manager/asset-manager.tsx @@ -56,7 +56,11 @@ export const TabContent = ({ onSetActiveTab("none"); }} /> - + diff --git a/apps/designer/app/designer/features/sidebar-left/panels/asset-manager/asset-thumbnail.tsx b/apps/designer/app/designer/features/sidebar-left/panels/asset-manager/asset-thumbnail.tsx index 9050ccdfef..58eb9f6a14 100644 --- a/apps/designer/app/designer/features/sidebar-left/panels/asset-manager/asset-thumbnail.tsx +++ b/apps/designer/app/designer/features/sidebar-left/panels/asset-manager/asset-thumbnail.tsx @@ -3,7 +3,7 @@ import { Box } from "@webstudio-is/design-system"; import placeholderImage from "~/shared/images/image-placeholder.svg"; import brokenImage from "~/shared/images/broken-image-placeholder.svg"; import { UploadingAnimation } from "./uploading-animation"; -import { AssetTooltip } from "./asset-tooltip"; +import { AssetInfoTrigger, assetInfoTriggerCssVars } from "./asset-info-tigger"; import { BaseAsset } from "./types"; const useImageWithFallback = ({ @@ -67,15 +67,12 @@ export const AssetThumbnail = (asset: BaseAsset) => { alignItems: "center", padding: "0 $2", position: "relative", - - "&:hover button": { - opacity: 1, - }, + "&:hover": assetInfoTriggerCssVars({ show: true }), }} > {isUploadedAsset && ( - setIsDeleting(true)} /> + setIsDeleting(true)} /> )} {(isUploading || isDeleting) && } diff --git a/apps/designer/package.json b/apps/designer/package.json index 615618ed94..5c7f39c1db 100644 --- a/apps/designer/package.json +++ b/apps/designer/package.json @@ -31,6 +31,7 @@ "@webstudio-is/icons": "*", "@webstudio-is/prisma-client": "*", "@webstudio-is/react-sdk": "*", + "@webstudio-is/css-vars": "*", "bson-objectid": "^2.0.2", "camelcase": "^6.3.0", "debug": "^4.3.4", diff --git a/packages/css-vars/LICENSE b/packages/css-vars/LICENSE new file mode 100644 index 0000000000..1f6edad9a7 --- /dev/null +++ b/packages/css-vars/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Webstudio + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/css-vars/README.md b/packages/css-vars/README.md new file mode 100644 index 0000000000..a38dc09433 --- /dev/null +++ b/packages/css-vars/README.md @@ -0,0 +1,13 @@ +# CSS Vars utils + +This package helps you create uniquely named css variables as well as use them. + +## Example + +```ts +import { cssVars } from "css-vars"; + +const myVariable = cssVars.define("my-variable"); // --my-variable-0 + +cssVars.use(myVariable, "fallback"); // var(--my-variable-0, fallback) +``` diff --git a/packages/css-vars/package.json b/packages/css-vars/package.json new file mode 100644 index 0000000000..04de169738 --- /dev/null +++ b/packages/css-vars/package.json @@ -0,0 +1,29 @@ +{ + "name": "@webstudio-is/css-vars", + "version": "0.1.0", + "description": "CSS vars utility", + "author": "Webstudio ", + "homepage": "https://webstudio.is", + "scripts": { + "typecheck": "tsc --noEmit", + "checks": "yarn typecheck && yarn lint", + "dev": "tsup src/index.ts --format esm,cjs --watch --out-dir=lib", + "build": "rm -fr lib && tsc", + "lint": "eslint ./src --ext .ts,.tsx --max-warnings 0" + }, + "dependencies": {}, + "devDependencies": { + "@webstudio-is/jest-config": "*", + "tsup": "^6.1.3", + "typescript": "^4.6.2" + }, + "main": "lib/index.js", + "types": "lib/index.d.ts", + "files": [ + "lib/*", + "README.md", + "!*.test.*" + ], + "license": "MIT", + "private": false +} diff --git a/packages/css-vars/src/index.ts b/packages/css-vars/src/index.ts new file mode 100644 index 0000000000..3085c36290 --- /dev/null +++ b/packages/css-vars/src/index.ts @@ -0,0 +1,21 @@ +let counter = -1; + +const define = (name: Name) => { + return `--${name}-${++counter}` as const; +}; + +type Cast = T1 extends T2 ? T1 : T2; + +type Join = T extends [] + ? "" + : T extends [string] + ? T[0] + : T extends [string, ...infer Rest] + ? `${T[0]}${D}${Join, D>}` + : never; + +const use = (...args: Args) => { + return `var(${args.join(", ") as Join})` as const; +}; + +export const cssVars = { define, use }; diff --git a/packages/css-vars/tsconfig.json b/packages/css-vars/tsconfig.json new file mode 100644 index 0000000000..6b67ca9bbf --- /dev/null +++ b/packages/css-vars/tsconfig.json @@ -0,0 +1,12 @@ +// Extends can't use node's resolution rn https://github.com/dividab/tsconfig-paths/issues/209#issuecomment-1177261091 +{ + "extends": "../../node_modules/@webstudio-is/tsconfig/base.json", + "include": ["./src/**/*.ts"], + "compilerOptions": { + "module": "commonjs", + "target": "ES2020", + "strict": true, + "baseUrl": ".", + "outDir": "./lib" + } +} diff --git a/packages/design-system/src/components/button.tsx b/packages/design-system/src/components/button.tsx index 01bed7974d..eb0394f82d 100644 --- a/packages/design-system/src/components/button.tsx +++ b/packages/design-system/src/components/button.tsx @@ -7,6 +7,7 @@ export const Button = styled("button", { boxSizing: "border-box", border: "none", userSelect: "none", + transition: "all 200ms ease-out", "&::before": { boxSizing: "border-box", }, @@ -83,24 +84,24 @@ export const Button = styled("button", { }, }, blue: { - backgroundColor: "$blue2", - boxShadow: "inset 0 0 0 1px $colors$blue7", - color: "$blue11", + backgroundColor: "$blue10", + color: "$loContrast", "@hover": { "&:hover": { - boxShadow: "inset 0 0 0 1px $colors$blue8", + backgroundColor: "$loContrast", + color: "$blue10", + boxShadow: "inset 0 0 0 1.5px $colors$blue10", }, }, "&:active": { - backgroundColor: "$blue3", - boxShadow: "inset 0 0 0 1px $colors$blue8", + boxShadow: "inset 0 0 0 1.5px $colors$blue8", }, "&:focus": { - boxShadow: "inset 0 0 0 1px $colors$blue8, 0 0 0 1px $colors$blue8", + boxShadow: + "inset 0 0 0 1.5px $colors$blue8, 0 0 0 1.5px $colors$blue8", }, '&[data-state="open"]': { - backgroundColor: "$blue4", - boxShadow: "inset 0 0 0 1px $colors$blue8", + boxShadow: "inset 0 0 0 1.5px $colors$blue8", }, }, green: { diff --git a/packages/icons/package.json b/packages/icons/package.json index e500e09f13..9ef9df0d2c 100644 --- a/packages/icons/package.json +++ b/packages/icons/package.json @@ -20,7 +20,8 @@ "react-dom": "^17.0.2" }, "dependencies": { - "@radix-ui/react-icons": "^1.1.0" + "@radix-ui/react-icons": "^1.1.0", + "@webstudio-is/css-vars": "*" }, "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/packages/icons/src/gear.tsx b/packages/icons/src/gear.tsx new file mode 100644 index 0000000000..f5f677fd5e --- /dev/null +++ b/packages/icons/src/gear.tsx @@ -0,0 +1,43 @@ +import { cssVars } from "@webstudio-is/css-vars"; +import * as React from "react"; +import { IconProps } from "./types"; + +const fillVar = cssVars.define("fill"); + +export const gearIconCssVars = ({ fill }: { fill: string }) => ({ + [fillVar]: fill, +}); + +export const GearIcon = React.forwardRef( + ({ color = "currentColor", ...props }, forwardedRef) => { + return ( + + + + + ); + } +); + +GearIcon.displayName = "GearIcon"; diff --git a/packages/icons/src/index.ts b/packages/icons/src/index.ts index cab70530d6..9cceef89b6 100644 --- a/packages/icons/src/index.ts +++ b/packages/icons/src/index.ts @@ -14,3 +14,5 @@ export { AspectRatioIcon } from "./aspect-ratio"; export * from "./cloud"; export { TrashIcon } from "./trash"; export { SizeIcon } from "./size"; +export { UploadIcon } from "./upload"; +export { GearIcon, gearIconCssVars } from "./gear"; diff --git a/packages/icons/src/upload.tsx b/packages/icons/src/upload.tsx new file mode 100644 index 0000000000..09afec0db2 --- /dev/null +++ b/packages/icons/src/upload.tsx @@ -0,0 +1,24 @@ +import * as React from "react"; +import { IconProps } from "./types"; + +export const UploadIcon = React.forwardRef( + ({ color = "currentColor", ...props }, forwardedRef) => { + return ( + + + + ); + } +); + +UploadIcon.displayName = "UploadIcon";