NODEDC_TASKMANAGER/handoff/image-picker-popover-uncomm...

131 lines
8.5 KiB
Diff

diff --git a/plane-src/apps/web/core/components/core/image-picker-popover.tsx b/plane-src/apps/web/core/components/core/image-picker-popover.tsx
index 431143a..0927b6e 100644
--- a/plane-src/apps/web/core/components/core/image-picker-popover.tsx
+++ b/plane-src/apps/web/core/components/core/image-picker-popover.tsx
@@ -12,6 +12,7 @@ import type { Control } from "react-hook-form";
import { Controller } from "react-hook-form";
import useSWR from "swr";
import { Popover } from "@headlessui/react";
+import { Check, UploadCloud } from "lucide-react";
// plane imports
import { ACCEPTED_COVER_IMAGE_MIME_TYPES_FOR_REACT_DROPZONE, MAX_FILE_SIZE } from "@plane/constants";
import { useOutsideClickDetector } from "@plane/hooks";
@@ -113,6 +114,7 @@ export const ImagePickerPopover = observer(function ImagePickerPopover(props: Pr
);
const imagePickerRef = useRef<HTMLDivElement>(null);
+ const selectedCoverImageUrl = value ? getCoverImageDisplayURL(value, null) : null;
const onDrop = useCallback((acceptedFiles: File[]) => {
setImage(acceptedFiles[0]);
@@ -215,17 +217,17 @@ export const ImagePickerPopover = observer(function ImagePickerPopover(props: Pr
{isOpen && (
<Popover.Panel
- className="nodedc-glass-modal nodedc-glass-popup-surface absolute right-0 z-20 mt-3 overflow-hidden rounded-[1.75rem]"
+ className="nodedc-glass-modal nodedc-glass-popup-surface absolute right-0 z-20 mt-3 overflow-hidden rounded-[1.9rem]"
static
>
<div
ref={imagePickerRef}
- className="flex h-[32rem] w-[21rem] flex-col overflow-hidden rounded-[1.75rem] md:h-[38rem] md:w-[38rem]"
+ className="nodedc-cover-picker flex h-[33rem] w-[21.5rem] flex-col overflow-hidden rounded-[1.9rem] md:h-[39rem] md:w-[42rem]"
>
<Tabs defaultValue={enabledTabs[0]?.key || "images"} className="flex h-full flex-col px-4 pt-4 pb-3">
- <Tabs.List className="rounded-[1rem] bg-layer-3/80 p-1">
+ <Tabs.List className="nodedc-cover-picker-tabs">
{enabledTabs.map((tab) => (
- <Tabs.Trigger key={tab.key} value={tab.key} size="md" className="rounded-[0.875rem]">
+ <Tabs.Trigger key={tab.key} value={tab.key} size="md" className="nodedc-cover-picker-tab">
{tab.title}
</Tabs.Trigger>
))}
@@ -273,7 +275,7 @@ export const ImagePickerPopover = observer(function ImagePickerPopover(props: Pr
{unsplashImages.map((image) => (
<div
key={image.id}
- className="nodedc-modal-field relative col-span-2 aspect-video overflow-hidden rounded-[1rem] p-0 md:col-span-1"
+ className="nodedc-cover-picker-tile group relative col-span-2 aspect-video overflow-hidden rounded-[1.2rem] p-0 md:col-span-1"
onClick={() => {
setIsOpen(false);
onChange(image.urls.regular);
@@ -282,7 +284,7 @@ export const ImagePickerPopover = observer(function ImagePickerPopover(props: Pr
<img
src={image.urls.small}
alt={image.alt_description}
- className="absolute inset-0 h-full w-full cursor-pointer rounded-[1rem] object-cover transition-transform duration-200 hover:scale-[1.02]"
+ className="absolute inset-0 h-full w-full cursor-pointer rounded-[1.2rem] object-cover transition-transform duration-200 group-hover:scale-[1.02]"
/>
</div>
))}
@@ -308,17 +310,25 @@ export const ImagePickerPopover = observer(function ImagePickerPopover(props: Pr
<Tabs.Content value="images" className="h-full w-full space-y-4">
<div className="grid grid-cols-4 gap-3">
{Object.values(STATIC_COVER_IMAGES).map((imageUrl, index) => (
- <div
+ <button
key={imageUrl}
- className="nodedc-modal-field relative col-span-2 aspect-video overflow-hidden rounded-[1rem] p-0 md:col-span-1"
+ type="button"
+ className="nodedc-cover-picker-tile group relative col-span-2 aspect-video overflow-hidden rounded-[1.2rem] p-0 text-left md:col-span-1"
+ data-selected={selectedCoverImageUrl === imageUrl}
onClick={() => handleStaticImageSelect(imageUrl)}
>
<img
src={imageUrl}
alt={t("image_picker.cover_image_alt", { index: index + 1 })}
- className="absolute inset-0 h-full w-full cursor-pointer rounded-[1rem] object-cover transition-transform duration-200 hover:scale-[1.02]"
+ className="absolute inset-0 h-full w-full cursor-pointer rounded-[1.2rem] object-cover transition-transform duration-200 group-hover:scale-[1.02]"
/>
- </div>
+ <div className="absolute inset-0 rounded-[1.2rem] bg-black/0 transition-colors duration-200 group-hover:bg-black/8" />
+ {selectedCoverImageUrl === imageUrl && (
+ <div className="absolute top-3 right-3 grid h-8 w-8 place-items-center rounded-full bg-[rgb(var(--nodedc-accent-rgb))] text-[rgb(var(--nodedc-on-accent-rgb))] shadow-[0_10px_24px_rgba(0,0,0,0.28)]">
+ <Check className="h-4 w-4" strokeWidth={2.4} />
+ </div>
+ )}
+ </button>
))}
</div>
</Tabs.Content>
@@ -327,9 +337,9 @@ export const ImagePickerPopover = observer(function ImagePickerPopover(props: Pr
<div className="flex w-full flex-1 items-center gap-3">
<div
{...getRootProps()}
- className={`nodedc-modal-field relative grid h-full w-full cursor-pointer place-items-center overflow-hidden rounded-[1.35rem] p-6 text-center ${
+ className={`nodedc-cover-picker-upload relative grid h-full w-full cursor-pointer place-items-center overflow-hidden rounded-[1.35rem] p-6 text-center ${
(image === null && isDragActive) || !value
- ? "border-2 border-dashed border-subtle/80 hover:bg-white/6"
+ ? "border-2 border-dashed border-white/10 hover:bg-white/6"
: ""
}`}
>
@@ -348,10 +358,16 @@ export const ImagePickerPopover = observer(function ImagePickerPopover(props: Pr
/>
</>
) : (
- <div>
- <span className="mt-2 block text-13 font-medium text-secondary">
+ <div className="flex max-w-[18rem] flex-col items-center gap-3">
+ <div className="grid h-12 w-12 place-items-center rounded-full bg-white/6 text-secondary">
+ <UploadCloud className="h-5 w-5" />
+ </div>
+ <span className="block text-13 font-medium text-secondary">
{isDragActive ? t("image_picker.drop_here_to_upload") : t("image_picker.drag_and_drop_here")}
</span>
+ <span className="text-12 text-tertiary">
+ {t("image_picker.supported_formats")}
+ </span>
</div>
)}
@@ -368,7 +384,7 @@ export const ImagePickerPopover = observer(function ImagePickerPopover(props: Pr
<p className="text-13 text-secondary">{t("image_picker.supported_formats")}</p>
- <div className="mt-auto flex items-start justify-end gap-3 border-t border-subtle/70 pt-4">
+ <div className="nodedc-cover-picker-footer mt-auto flex items-start justify-end gap-3 border-t border-subtle/70 pt-4">
<Button
variant="secondary"
onClick={() => {