-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Update UI for "download datasets" (#5796)
Co-authored-by: Fran McDade <franmcdade@Frans-MacBook-Pro.local> Co-authored-by: Fran McDade <frano-m@users.noreply.github.com>
- Loading branch information
1 parent
522ae3c
commit 7e3ccca
Showing
26 changed files
with
864 additions
and
350 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
export enum FEATURES { | ||
DOWNLOAD_UX = "dux", | ||
GENE_SETS = "gs", | ||
CURATOR = "curator", | ||
FILTER = "filter", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 0 additions & 8 deletions
8
...ents/Collection/components/CollectionDatasetsGrid/components/Row/DownloadDataset/style.ts
This file was deleted.
Oops, something went wrong.
46 changes: 0 additions & 46 deletions
46
frontend/src/components/Collections/components/Dataset/common/style.ts
This file was deleted.
Oops, something went wrong.
60 changes: 60 additions & 0 deletions
60
...DownloadDataset/components/Content/components/CurlLink/components/CopyButton/constants.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { FadeProps } from "@mui/material"; | ||
|
||
export interface Animation | ||
extends Pick<FadeProps, "easing" | "in" | "timeout"> { | ||
duration: number; | ||
isCopying: boolean; | ||
} | ||
|
||
const ANIMATION_300_EASE_OUT = { | ||
easing: "ease-out", | ||
timeout: 250, | ||
}; | ||
|
||
const ANIMATION_200_EASE_IN = { | ||
easing: "ease-in", | ||
timeout: 150, | ||
}; | ||
|
||
// Possible animation step values. | ||
export enum ANIMATION_STEP { | ||
COPIED_ENTER = 2, | ||
COPIED_EXIT = 3, | ||
COPY_ENTER = 4, | ||
COPY_EXIT = 1, | ||
IDLE = 0, | ||
} | ||
|
||
// Animation properties for each step. | ||
export const ANIMATION: Record<ANIMATION_STEP, Animation> = { | ||
[ANIMATION_STEP.IDLE]: { | ||
...ANIMATION_300_EASE_OUT, | ||
in: true, | ||
isCopying: false, | ||
duration: 0, | ||
}, | ||
[ANIMATION_STEP.COPY_EXIT]: { | ||
...ANIMATION_300_EASE_OUT, | ||
in: false, | ||
isCopying: true, | ||
duration: 0, | ||
}, | ||
[ANIMATION_STEP.COPIED_ENTER]: { | ||
...ANIMATION_300_EASE_OUT, | ||
in: true, | ||
isCopying: true, | ||
duration: 1000, // Show "Copied" for 1 second. | ||
}, | ||
[ANIMATION_STEP.COPIED_EXIT]: { | ||
...ANIMATION_200_EASE_IN, | ||
in: false, | ||
isCopying: true, | ||
duration: 0, | ||
}, | ||
[ANIMATION_STEP.COPY_ENTER]: { | ||
...ANIMATION_200_EASE_IN, | ||
in: true, | ||
isCopying: true, | ||
duration: 0, | ||
}, | ||
}; |
95 changes: 95 additions & 0 deletions
95
...ts/DownloadDataset/components/Content/components/CurlLink/components/CopyButton/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import copy from "clipboard-copy"; | ||
import { useEffect, useRef, useState } from "react"; | ||
import { CopyButton as Button } from "./style"; | ||
import { Fade } from "@mui/material"; | ||
import { ANIMATION, ANIMATION_STEP } from "./constants"; | ||
|
||
interface Props { | ||
curl: string; | ||
handleAnalytics: () => void; | ||
} | ||
|
||
export default function CopyButton({ | ||
curl, | ||
handleAnalytics, | ||
}: Props): JSX.Element { | ||
const [animationStep, setAnimationStep] = useState<ANIMATION_STEP>( | ||
ANIMATION_STEP.IDLE | ||
); | ||
const timeoutRef = useRef<NodeJS.Timer>(); | ||
const animation = ANIMATION[animationStep]; | ||
|
||
// Copy to clipboard, handle analytics, and initiate the copy animation. | ||
const handleCopyClick = () => { | ||
if (animation.isCopying) { | ||
return; // Copying is in progress. | ||
} | ||
copy(curl); | ||
handleAnalytics(); | ||
setAnimationStep(incrementAnimationState); | ||
}; | ||
|
||
// Callback fired after the "exited" or "entered" status is applied. | ||
// Executes while copy animation is in progress for "COPY_EXIT", "COPIED_ENTER" and "COPIED_EXIT", "COPY_ENTER". | ||
// Increments the animation step. | ||
const onUpdateAnimationStep = () => { | ||
timeoutRef.current = setTimeout(() => { | ||
// Executes the next animation progression, after duration of the current animation is complete. | ||
setAnimationStep(incrementAnimationState); | ||
}, animation.duration); | ||
}; | ||
|
||
// Clears timeout when unmounting. | ||
useEffect(() => { | ||
return () => { | ||
clearTimeout(timeoutRef.current); | ||
}; | ||
}, []); | ||
|
||
return ( | ||
<Button | ||
isAllCaps={false} | ||
onClick={handleCopyClick} | ||
sdsStyle="minimal" | ||
sdsType="primary" | ||
> | ||
<Fade | ||
appear={false} | ||
easing={animation.easing} | ||
in={animation.in} | ||
onEntered={onUpdateAnimationStep} | ||
onExited={onUpdateAnimationStep} | ||
timeout={animation.timeout} | ||
> | ||
<span>{getButtonText(animationStep)}</span> | ||
</Fade> | ||
</Button> | ||
); | ||
} | ||
|
||
/** | ||
* Returns the button text to display. | ||
* @param step - Current animation step. | ||
* @returns button text. | ||
*/ | ||
function getButtonText(step: number): string { | ||
if ( | ||
step === ANIMATION_STEP.COPIED_ENTER || | ||
step === ANIMATION_STEP.COPIED_EXIT | ||
) { | ||
return "Copied"; | ||
} | ||
return "Copy"; | ||
} | ||
|
||
/** | ||
* Increments the animation step. | ||
* @param step - Current animation step. | ||
* @returns next animation step. | ||
*/ | ||
function incrementAnimationState(step: number): number { | ||
if (step === ANIMATION_STEP.COPY_ENTER) { | ||
return ANIMATION_STEP.IDLE; | ||
} | ||
return step + 1; | ||
} |
8 changes: 8 additions & 0 deletions
8
...nts/DownloadDataset/components/Content/components/CurlLink/components/CopyButton/style.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import styled from "@emotion/styled"; | ||
import { Button, fontBodyS } from "@czi-sds/components"; | ||
|
||
export const CopyButton = styled(Button)` | ||
${fontBodyS} | ||
font-weight: 500; | ||
min-width: unset; | ||
`; |
36 changes: 36 additions & 0 deletions
36
...ents/DownloadDataset/components/Content/components/CurlLink/components/CopyMask/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import copy from "clipboard-copy"; | ||
import { useState } from "react"; | ||
import { CopyMask as Mask } from "./style"; | ||
|
||
interface Props { | ||
curl: string; | ||
handleAnalytics: () => void; | ||
} | ||
|
||
/** | ||
* @deprecated by CopyButton component once "DOWNLOAD_UX" feature flag is removed (#5566). | ||
*/ | ||
export default function CopyMask({ | ||
curl, | ||
handleAnalytics, | ||
}: Props): JSX.Element { | ||
const [isCopied, setIsCopied] = useState<boolean>(false); | ||
|
||
// Copy to clipboard, handle analytics. | ||
const handleCopyClick = () => { | ||
setIsCopied(true); | ||
copy(curl); | ||
handleAnalytics(); | ||
}; | ||
|
||
// Handle mouse enter event to reset the copy state. | ||
const onMouseEnter = () => { | ||
setIsCopied(false); | ||
}; | ||
|
||
return ( | ||
<Mask onClick={handleCopyClick} onMouseEnter={onMouseEnter}> | ||
{isCopied ? "Copied!" : "Copy to Clipboard"} | ||
</Mask> | ||
); | ||
} |
25 changes: 25 additions & 0 deletions
25
...nents/DownloadDataset/components/Content/components/CurlLink/components/CopyMask/style.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import styled from "@emotion/styled"; | ||
import { fontBodyS } from "@czi-sds/components"; | ||
|
||
export const CopyMask = styled.div` | ||
${fontBodyS} | ||
align-items: center; | ||
background-color: rgba(0, 118, 220, 0.9); | ||
color: white; | ||
cursor: pointer; | ||
display: flex; | ||
font-size: 16px; | ||
height: 100%; | ||
justify-content: center; | ||
left: 0; | ||
letter-spacing: normal; | ||
line-height: inherit; | ||
opacity: 0; | ||
position: absolute; | ||
top: 0; | ||
width: 100%; | ||
&:hover { | ||
opacity: 1; | ||
} | ||
`; |
Oops, something went wrong.