Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Activities bar - added carousel #287

Merged
merged 20 commits into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions dapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@sentry/react": "^7.98.0",
"@sentry/types": "^7.102.0",
"@tanstack/react-table": "^8.11.3",
"@types/react-slick": "^0.23.13",
"axios": "^1.6.7",
"ethers": "^6.10.0",
"formik": "^2.4.5",
Expand All @@ -34,6 +35,7 @@
"react-number-format": "^5.3.1",
"react-redux": "^9.1.0",
"react-router-dom": "^6.22.0",
"react-slick": "^0.30.2",
"recharts": "^2.12.0"
},
"devDependencies": {
Expand Down
69 changes: 69 additions & 0 deletions dapp/src/assets/icons/animated/ArrowUpRightAnimatedIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React from "react"
import { ArrowUpRight } from "#/assets/icons"
import { Box, Icon } from "@chakra-ui/react"
import { Variants, motion } from "framer-motion"
import { chakraUnitToPx } from "#/theme/utils"

const arrowUpVariants: Variants = {
initial: {
x: 0,
y: -5,
},
animate: (boxSizePx: number) => ({
x: [0, boxSizePx],
y: [-5, -boxSizePx],
transition: {
duration: 0.4,
ease: "easeInOut",
},
}),
}

const arrowBottomVariants: Variants = {
initial: (boxSizePx: number) => ({
x: -boxSizePx,
y: boxSizePx,
}),
animate: (boxSizePx: number) => ({
x: [-boxSizePx, 0],
y: [boxSizePx, -5],
transition: {
duration: 0.4,
ease: "easeInOut",
},
}),
}

type ArrowUpRightAnimatedIconProps = {
boxSize?: number
color?: string
}

export function ArrowUpRightAnimatedIcon({
boxSize = 4,
color = "brand.400",
}: ArrowUpRightAnimatedIconProps) {
const boxSizePx = chakraUnitToPx(boxSize)
return (
<Box pos="relative" boxSize={boxSize} overflow="hidden">
<Box
pos="absolute"
as={motion.div}
boxSize={boxSize}
custom={boxSizePx}
variants={arrowUpVariants}
>
<Icon as={ArrowUpRight} boxSize={boxSize} color={color} />
</Box>
<Box
pos="absolute"
as={motion.div}
boxSize={boxSize}
custom={boxSizePx}
variants={arrowBottomVariants}
>
<Icon as={ArrowUpRight} boxSize={boxSize} color={color} />
</Box>
kkosiorowska marked this conversation as resolved.
Show resolved Hide resolved
</Box>
)
}
1 change: 1 addition & 0 deletions dapp/src/assets/icons/animated/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./ArrowUpRightAnimatedIcon"
11 changes: 11 additions & 0 deletions dapp/src/components/GlobalStyles/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ export default function GlobalStyles() {
font-weight: 900;
font-style: normal;
}
// React-slick package: Chakra-ui with react-slick package doesn't
// generate flex style for auto-generated slick-track wrapper.
.slick-track {
display: flex;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me that this is not a problem related to Chakra but to the fact that we have not imported styles.

Copy link
Contributor Author

@ioay ioay Mar 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if importing additional styles and then overriding the imported styles is needed. To add this kind of style with a lot of we have to install the additional package: slick-carousel or import them from cdn, another option is to add all these styles into the global styles file which leads to the same thing, only with more styles to remove/overwrite.

We just need to add display: flex to the slick-track class (this class is generated under the hood of react-slick, so we can't style it directly in the Carousel component). I'd leave it as it is if you don't mind.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following this approach, let's add a right description of why we do this. Let's document this decision.

// React-slick package: Hiding arrows instead of disabling them in case
// when carousel is not fully completed by slides.
[data-id="slick-arrow-prev"]:disabled:has(~ [data-id="slick-arrow-next"]:disabled),
[data-id="slick-arrow-prev"]:disabled ~ [data-id="slick-arrow-next"]:disabled{
display: none;
}
Comment on lines +53 to +56
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should not do it in global styles but in the code related to this carousel. But we can leave it that way now and move it in the future if needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably won't change it also for other carousel components if appears. I added a comment to this style when was created:

// React-slick package: Hiding arrows instead of disabling them in case 
// when carousel is not fully completed by slides.

`}
/>
)
Expand Down
35 changes: 0 additions & 35 deletions dapp/src/components/shared/ActivityBar/index.tsx

This file was deleted.

25 changes: 0 additions & 25 deletions dapp/src/components/shared/ActivityBar/mock-activities.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,36 @@ import {
Tooltip,
CloseButton,
} from "@chakra-ui/react"
import { useLocation } from "react-router-dom"
import { ActivityInfo, LocationState } from "#/types"
import { capitalize } from "#/utils"
import { useNavigate } from "react-router-dom"
import { ActivityInfo } from "#/types"
import { ChevronRightIcon } from "#/assets/icons"
import { CurrencyBalance } from "#/components/shared/CurrencyBalance"
import StatusInfo from "#/components/shared/StatusInfo"
import { TextSm } from "#/components/shared/Typography"
import ActivityCardContainer from "./ActivityCardContainer"
import { routerPath } from "#/router/path"
import { ActivityCardWrapper } from "./ActivityCardWrapper"

type ActivityCardType = CardProps & {
activity: ActivityInfo
onRemove: (txHash: string) => void
isActive?: boolean
}

function ActivityCard({ activity, onRemove }: ActivityCardType) {
const state = useLocation().state as LocationState | null
const isActive = state ? activity.txHash === state.activity.txHash : false
export function ActivityCard({
activity,
onRemove,
isActive,
}: ActivityCardType) {
const navigate = useNavigate()
const isCompleted = activity.status === "completed"

const onClick = useCallback(() => {
navigate(`${routerPath.activity}/${activity.txHash}`)
}, [activity.txHash, navigate])

const onClose = useCallback(
(event: React.MouseEvent) => {
event.preventDefault()
event.stopPropagation()
if (activity.txHash) {
onRemove(activity.txHash)
}
Expand All @@ -39,7 +47,11 @@ function ActivityCard({ activity, onRemove }: ActivityCardType) {
)

return (
<ActivityCardContainer isCompleted={isCompleted} isActive={isActive}>
<ActivityCardWrapper
isCompleted={isCompleted}
isActive={isActive}
onClick={onClick}
>
<CardHeader p={0} w="100%">
<HStack justifyContent="space-between">
<CurrencyBalance
Expand Down Expand Up @@ -67,9 +79,9 @@ function ActivityCard({ activity, onRemove }: ActivityCardType) {
)}
</HStack>
</CardHeader>
<CardBody p={0}>
<TextSm fontWeight="semibold" marginBottom={4}>
{capitalize(activity.action)}
<CardBody p={0} pb={4}>
<TextSm fontWeight="semibold" textTransform="capitalize">
{activity.action}
</TextSm>
</CardBody>
<CardFooter p={0}>
Expand All @@ -80,8 +92,6 @@ function ActivityCard({ activity, onRemove }: ActivityCardType) {
fontWeight="medium"
/>
</CardFooter>
</ActivityCardContainer>
</ActivityCardWrapper>
)
}

export default ActivityCard
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from "react"
import { CardProps, Card } from "@chakra-ui/react"

type ActivityCardContainerProps = CardProps & {
type ActivityCardWrapperProps = CardProps & {
isCompleted: boolean
isActive: boolean
children: React.ReactNode
isActive?: boolean
}

const completedStyles = {
Expand Down Expand Up @@ -34,18 +34,19 @@ const activeStyles = {
},
}

function ActivityCardContainer({
export function ActivityCardWrapper({
isActive,
isCompleted,
children,
...props
}: ActivityCardContainerProps) {
}: ActivityCardWrapperProps) {
return (
<Card
{...props}
width={64}
paddingX={5}
padding={3}
w={64}
mr={3}
px={5}
p={3}
cursor="pointer"
borderWidth={1}
borderColor="gold.100"
_hover={{
Expand All @@ -55,10 +56,9 @@ function ActivityCardContainer({
}}
{...(isActive && activeStyles)}
{...(isCompleted && completedStyles)}
{...props}
>
{children}
</Card>
)
}

export default ActivityCardContainer
1 change: 1 addition & 0 deletions dapp/src/components/shared/ActivityCard/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./ActivityCard"
32 changes: 32 additions & 0 deletions dapp/src/components/shared/Carousel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React, { forwardRef } from "react"
import { FlexProps, Flex } from "@chakra-ui/react"
import Slider, { Settings as SliderProps } from "react-slick"

const carouselSettings: SliderProps = {
dots: false,
infinite: false,
draggable: false,
variableWidth: true,
speed: 500,
slidesToShow: 12,
slidesToScroll: 1,
}

type CarouselProps = FlexProps &
SliderProps & {
children: React.ReactNode
}

export const Carousel = forwardRef<HTMLInputElement, CarouselProps>(
(props, ref) => (
<Flex
as={Slider}
ref={ref}
overflowX="hidden"
kkosiorowska marked this conversation as resolved.
Show resolved Hide resolved
{...carouselSettings}
{...props}
>
{props.children}
</Flex>
),
)
1 change: 1 addition & 0 deletions dapp/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ export * from "./useInitApp"
export * from "./useCurrencyConversion"
export * from "./useDepositTelemetry"
export * from "./useFetchBTCPriceUSD"
export * from "./useActivities"
25 changes: 25 additions & 0 deletions dapp/src/hooks/useActivities.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { useCallback, useState } from "react"
import { mockedActivities } from "#/mock"

export function useActivities() {
// TODO: should be replaced by redux store when subgraphs are implemented
const [activities, setActivities] = useState(mockedActivities)

const getActivity = useCallback(
(activityId?: string) =>
activities.find((_activity) => _activity.txHash === activityId),
[activities],
)

const onRemove = useCallback(
(activityHash: string) => {
const filteredActivities = activities.filter(
(activity) => activity.txHash !== activityHash,
)
setActivities(filteredActivities)
},
[activities],
)

return { activities, getActivity, onRemove }
}
1 change: 1 addition & 0 deletions dapp/src/mock/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./mock-activities"
Loading
Loading