Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
frontend
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
frontend
Commits
50676eb5
Commit
50676eb5
authored
Feb 26, 2025
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
link overlay component
parent
2fff1760
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
97 additions
and
44 deletions
+97
-44
eslint.config.mjs
eslint.config.mjs
+2
-2
link.tsx
toolkit/chakra/link.tsx
+47
-10
FeaturedApp.tsx
ui/marketplace/Banner/FeaturedApp.tsx
+12
-15
FeaturedAppMobile.tsx
ui/marketplace/Banner/FeaturedAppMobile.tsx
+2
-2
MarketplaceAppCard.tsx
ui/marketplace/MarketplaceAppCard.tsx
+2
-2
MarketplaceAppCardLink.tsx
ui/marketplace/MarketplaceAppCardLink.tsx
+12
-11
NftHtml.tsx
ui/shared/nft/NftHtml.tsx
+3
-1
Link.tsx
ui/showcases/Link.tsx
+17
-1
No files found.
eslint.config.mjs
View file @
50676eb5
...
@@ -32,8 +32,8 @@ const RESTRICTED_MODULES = {
...
@@ -32,8 +32,8 @@ const RESTRICTED_MODULES = {
{
{
name
:
'
@chakra-ui/react
'
,
name
:
'
@chakra-ui/react
'
,
importNames
:
[
importNames
:
[
'
Menu
'
,
'
useToast
'
,
'
useDisclosure
'
,
'
useClipboard
'
,
'
Tooltip
'
,
'
Skeleton
'
,
'
IconButton
'
,
'
Button
'
,
'
ButtonGroup
'
,
'
Link
'
,
'
Tag
'
,
'
Switch
'
,
'
Menu
'
,
'
useToast
'
,
'
useDisclosure
'
,
'
useClipboard
'
,
'
Tooltip
'
,
'
Skeleton
'
,
'
IconButton
'
,
'
Button
'
,
'
ButtonGroup
'
,
'
Link
'
,
'
LinkBox
'
,
'
LinkOverlay
'
,
'
Image
'
,
'
Popover
'
,
'
PopoverTrigger
'
,
'
PopoverContent
'
,
'
PopoverBody
'
,
'
PopoverFooter
'
,
'
Tag
'
,
'
Switch
'
,
'
Image
'
,
'
Popover
'
,
'
PopoverTrigger
'
,
'
PopoverContent
'
,
'
PopoverBody
'
,
'
PopoverFooter
'
,
'
DrawerRoot
'
,
'
DrawerBody
'
,
'
DrawerContent
'
,
'
DrawerOverlay
'
,
'
DrawerBackdrop
'
,
'
DrawerTrigger
'
,
'
Drawer
'
,
'
DrawerRoot
'
,
'
DrawerBody
'
,
'
DrawerContent
'
,
'
DrawerOverlay
'
,
'
DrawerBackdrop
'
,
'
DrawerTrigger
'
,
'
Drawer
'
,
'
Alert
'
,
'
AlertIcon
'
,
'
AlertTitle
'
,
'
AlertDescription
'
,
'
Alert
'
,
'
AlertIcon
'
,
'
AlertTitle
'
,
'
AlertDescription
'
,
'
Heading
'
,
'
Badge
'
,
'
Tabs
'
,
'
Show
'
,
'
Hide
'
,
'
Checkbox
'
,
'
Heading
'
,
'
Badge
'
,
'
Tabs
'
,
'
Show
'
,
'
Hide
'
,
'
Checkbox
'
,
...
...
toolkit/chakra/link.tsx
View file @
50676eb5
import
type
{
LinkProps
as
ChakraLinkProps
}
from
'
@chakra-ui/react
'
;
import
type
{
LinkProps
as
ChakraLinkProps
}
from
'
@chakra-ui/react
'
;
import
{
Link
as
ChakraLink
}
from
'
@chakra-ui/react
'
;
import
{
Link
as
ChakraLink
,
LinkBox
as
ChakraLinkBox
,
LinkOverlay
as
ChakraLinkOverlay
}
from
'
@chakra-ui/react
'
;
import
NextLink
from
'
next/link
'
;
import
NextLink
from
'
next/link
'
;
import
type
{
LinkProps
as
NextLinkProps
}
from
'
next/link
'
;
import
type
{
LinkProps
as
NextLinkProps
}
from
'
next/link
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
...
@@ -21,7 +21,7 @@ export const LinkExternalIcon = ({ color }: { color?: ChakraLinkProps['color'] }
...
@@ -21,7 +21,7 @@ export const LinkExternalIcon = ({ color }: { color?: ChakraLinkProps['color'] }
/>
/>
);
);
export
interface
LinkProps
extends
Pick
<
NextLinkProps
,
'
shallow
'
|
'
prefetch
'
|
'
scroll
'
>
,
ChakraLinkProps
{
interface
LinkPropsChakra
extends
ChakraLinkProps
{
loading
?:
boolean
;
loading
?:
boolean
;
external
?:
boolean
;
external
?:
boolean
;
iconColor
?:
ChakraLinkProps
[
'
color
'
];
iconColor
?:
ChakraLinkProps
[
'
color
'
];
...
@@ -29,9 +29,28 @@ export interface LinkProps extends Pick<NextLinkProps, 'shallow' | 'prefetch' |
...
@@ -29,9 +29,28 @@ export interface LinkProps extends Pick<NextLinkProps, 'shallow' | 'prefetch' |
disabled
?:
boolean
;
disabled
?:
boolean
;
}
}
interface
LinkPropsNext
extends
Pick
<
NextLinkProps
,
'
shallow
'
|
'
prefetch
'
|
'
scroll
'
>
{}
export
interface
LinkProps
extends
LinkPropsChakra
,
LinkPropsNext
{}
const
splitProps
=
(
props
:
LinkProps
):
{
chakra
:
LinkPropsChakra
;
next
:
NextLinkProps
}
=>
{
const
{
scroll
=
true
,
shallow
=
false
,
prefetch
=
false
,
...
rest
}
=
props
;
return
{
chakra
:
rest
,
next
:
{
href
:
rest
.
href
as
NextLinkProps
[
'
href
'
],
scroll
,
shallow
,
prefetch
,
},
};
};
export
const
Link
=
React
.
forwardRef
<
HTMLAnchorElement
,
LinkProps
>
(
export
const
Link
=
React
.
forwardRef
<
HTMLAnchorElement
,
LinkProps
>
(
function
Link
(
props
,
ref
)
{
function
Link
(
props
,
ref
)
{
const
{
external
,
loading
,
href
,
children
,
scroll
=
true
,
iconColor
,
noIcon
,
shallow
,
prefetch
=
false
,
disabled
,
...
rest
}
=
props
;
const
{
chakra
,
next
}
=
splitProps
(
props
);
const
{
external
,
loading
,
href
,
children
,
disabled
,
noIcon
,
iconColor
,
...
rest
}
=
chakra
;
if
(
external
)
{
if
(
external
)
{
return
(
return
(
...
@@ -60,13 +79,8 @@ export const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(
...
@@ -60,13 +79,8 @@ export const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(
{
...
(
disabled
?
{
'
data
-
disabled
':
true
}
:
{})
}
{
...
(
disabled
?
{
'
data
-
disabled
':
true
}
:
{})
}
{
...
rest
}
{
...
rest
}
>
>
{
href
?
(
{
next
.
href
?
(
<
NextLink
<
NextLink
{
...
next
}
>
href=
{
href
as
NextLinkProps
[
'
href
'
]
}
scroll=
{
scroll
}
shallow=
{
shallow
}
prefetch=
{
prefetch
}
>
{
children
}
{
children
}
</
NextLink
>
</
NextLink
>
)
:
)
:
...
@@ -77,3 +91,26 @@ export const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(
...
@@ -77,3 +91,26 @@ export const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(
);
);
},
},
);
);
export
const
LinkBox
=
ChakraLinkBox
;
export
const
LinkOverlay
=
React
.
forwardRef
<
HTMLAnchorElement
,
LinkProps
>
(
function
LinkOverlay
(
props
,
ref
)
{
const
{
chakra
,
next
}
=
splitProps
(
props
);
const
{
children
,
external
,
...
rest
}
=
chakra
;
if
(
external
)
{
return
(
<
ChakraLinkOverlay
ref=
{
ref
}
target=
"_blank"
rel=
"noopener noreferrer"
{
...
rest
}
>
{
children
}
</
ChakraLinkOverlay
>
);
}
return
(
<
ChakraLinkOverlay
ref=
{
ref
}
asChild=
{
Boolean
(
next
.
href
)
}
{
...
rest
}
>
{
next
.
href
?
<
NextLink
{
...
next
}
>
{
children
}
</
NextLink
>
:
children
}
</
ChakraLinkOverlay
>
);
},
);
ui/marketplace/Banner/FeaturedApp.tsx
View file @
50676eb5
import
{
LinkBox
,
Flex
,
LinkOverlay
,
Text
}
from
'
@chakra-ui/react
'
;
import
{
Flex
,
Text
}
from
'
@chakra-ui/react
'
;
import
type
{
MouseEvent
}
from
'
react
'
;
import
type
{
MouseEvent
}
from
'
react
'
;
import
React
,
{
useCallback
}
from
'
react
'
;
import
React
,
{
useCallback
}
from
'
react
'
;
import
type
{
MarketplaceAppPreview
}
from
'
types/client/marketplace
'
;
import
type
{
MarketplaceAppPreview
}
from
'
types/client/marketplace
'
;
import
{
route
}
from
'
nextjs-routes
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
*
as
mixpanel
from
'
lib/mixpanel/index
'
;
import
*
as
mixpanel
from
'
lib/mixpanel/index
'
;
import
{
useColorModeValue
}
from
'
toolkit/chakra/color-mode
'
;
import
{
useColorModeValue
}
from
'
toolkit/chakra/color-mode
'
;
import
{
IconButton
}
from
'
toolkit/chakra/icon-button
'
;
import
{
IconButton
}
from
'
toolkit/chakra/icon-button
'
;
import
{
Image
}
from
'
toolkit/chakra/image
'
;
import
{
Image
}
from
'
toolkit/chakra/image
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
{
Link
,
LinkBox
,
LinkOverlay
}
from
'
toolkit/chakra/link
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
NextLink
from
'
ui/shared/NextLink
'
;
import
FavoriteIcon
from
'
../FavoriteIcon
'
;
import
FavoriteIcon
from
'
../FavoriteIcon
'
;
import
MarketplaceAppIntegrationIcon
from
'
../MarketplaceAppIntegrationIcon
'
;
import
MarketplaceAppIntegrationIcon
from
'
../MarketplaceAppIntegrationIcon
'
;
...
@@ -60,7 +61,7 @@ const FeaturedApp = ({
...
@@ -60,7 +61,7 @@ const FeaturedApp = ({
}
}
return
(
return
(
<
LinkBox
role=
"group"
>
<
LinkBox
>
<
Flex
<
Flex
gap=
{
6
}
gap=
{
6
}
borderRadius=
"md"
borderRadius=
"md"
...
@@ -94,17 +95,13 @@ const FeaturedApp = ({
...
@@ -94,17 +95,13 @@ const FeaturedApp = ({
fontFamily=
"heading"
fontFamily=
"heading"
lineHeight=
"36px"
lineHeight=
"36px"
>
>
{
external
?
(
<
LinkOverlay
<
LinkOverlay
href=
{
url
}
target=
"_blank"
marginRight=
{
2
}
>
href=
{
external
?
url
:
route
({
pathname
:
'
/apps/[id]
'
,
query
:
{
id
}
})
}
{
title
}
marginRight=
{
2
}
</
LinkOverlay
>
external=
{
external
}
)
:
(
>
<
NextLink
href=
{
{
pathname
:
'
/apps/[id]
'
,
query
:
{
id
}
}
}
passHref
legacyBehavior
>
{
title
}
<
LinkOverlay
marginRight=
{
2
}
>
</
LinkOverlay
>
{
title
}
</
LinkOverlay
>
</
NextLink
>
)
}
<
MarketplaceAppIntegrationIcon
external=
{
external
}
internalWallet=
{
internalWallet
}
/>
<
MarketplaceAppIntegrationIcon
external=
{
external
}
internalWallet=
{
internalWallet
}
/>
</
Skeleton
>
</
Skeleton
>
...
...
ui/marketplace/Banner/FeaturedAppMobile.tsx
View file @
50676eb5
import
{
LinkBox
,
Flex
,
Text
}
from
'
@chakra-ui/react
'
;
import
{
Flex
,
Text
}
from
'
@chakra-ui/react
'
;
import
type
{
MouseEvent
}
from
'
react
'
;
import
type
{
MouseEvent
}
from
'
react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
...
@@ -7,7 +7,7 @@ import type { MarketplaceAppPreview } from 'types/client/marketplace';
...
@@ -7,7 +7,7 @@ import type { MarketplaceAppPreview } from 'types/client/marketplace';
import
{
useColorModeValue
}
from
'
toolkit/chakra/color-mode
'
;
import
{
useColorModeValue
}
from
'
toolkit/chakra/color-mode
'
;
import
{
IconButton
}
from
'
toolkit/chakra/icon-button
'
;
import
{
IconButton
}
from
'
toolkit/chakra/icon-button
'
;
import
{
Image
}
from
'
toolkit/chakra/image
'
;
import
{
Image
}
from
'
toolkit/chakra/image
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
{
Link
,
LinkBox
}
from
'
toolkit/chakra/link
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
FavoriteIcon
from
'
../FavoriteIcon
'
;
import
FavoriteIcon
from
'
../FavoriteIcon
'
;
...
...
ui/marketplace/MarketplaceAppCard.tsx
View file @
50676eb5
import
{
LinkBox
,
chakra
,
Flex
,
Text
}
from
'
@chakra-ui/react
'
;
import
{
chakra
,
Flex
,
Text
}
from
'
@chakra-ui/react
'
;
import
type
{
MouseEvent
}
from
'
react
'
;
import
type
{
MouseEvent
}
from
'
react
'
;
import
React
,
{
useCallback
}
from
'
react
'
;
import
React
,
{
useCallback
}
from
'
react
'
;
...
@@ -9,7 +9,7 @@ import isBrowser from 'lib/isBrowser';
...
@@ -9,7 +9,7 @@ import isBrowser from 'lib/isBrowser';
import
{
useColorModeValue
}
from
'
toolkit/chakra/color-mode
'
;
import
{
useColorModeValue
}
from
'
toolkit/chakra/color-mode
'
;
import
{
IconButton
}
from
'
toolkit/chakra/icon-button
'
;
import
{
IconButton
}
from
'
toolkit/chakra/icon-button
'
;
import
{
Image
}
from
'
toolkit/chakra/image
'
;
import
{
Image
}
from
'
toolkit/chakra/image
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
{
Link
,
LinkBox
}
from
'
toolkit/chakra/link
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
CopyToClipboard
from
'
ui/shared/CopyToClipboard
'
;
import
CopyToClipboard
from
'
ui/shared/CopyToClipboard
'
;
...
...
ui/marketplace/MarketplaceAppCardLink.tsx
View file @
50676eb5
import
{
LinkOverlay
,
chakra
}
from
'
@chakra-ui/react
'
;
import
{
chakra
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
type
{
MouseEvent
}
from
'
react
'
;
import
type
{
MouseEvent
}
from
'
react
'
;
import
NextLink
from
'
ui/shared/NextLink
'
;
import
{
route
}
from
'
nextjs-routes
'
;
import
{
LinkOverlay
}
from
'
toolkit/chakra/link
'
;
type
Props
=
{
type
Props
=
{
id
:
string
;
id
:
string
;
...
@@ -18,17 +20,16 @@ const MarketplaceAppCardLink = ({ url, external, id, title, onClick, className }
...
@@ -18,17 +20,16 @@ const MarketplaceAppCardLink = ({ url, external, id, title, onClick, className }
onClick
?.(
event
,
id
);
onClick
?.(
event
,
id
);
},
[
onClick
,
id
]);
},
[
onClick
,
id
]);
// TODO @tom2drum create LinkOverlay component
return
(
return
external
?
(
<
LinkOverlay
<
LinkOverlay
href=
{
url
}
marginRight=
{
2
}
className=
{
className
}
target=
"_blank"
>
href=
{
external
?
url
:
route
({
pathname
:
'
/apps/[id]
'
,
query
:
{
id
}
})
}
marginRight=
{
2
}
className=
{
className
}
external=
{
external
}
onClick=
{
handleClick
}
>
{
title
}
{
title
}
</
LinkOverlay
>
</
LinkOverlay
>
)
:
(
<
NextLink
href=
{
{
pathname
:
'
/apps/[id]
'
,
query
:
{
id
}
}
}
passHref
legacyBehavior
>
<
LinkOverlay
onClick=
{
handleClick
}
marginRight=
{
2
}
className=
{
className
}
>
{
title
}
</
LinkOverlay
>
</
NextLink
>
);
);
};
};
...
...
ui/shared/nft/NftHtml.tsx
View file @
50676eb5
import
{
chakra
,
LinkOverlay
}
from
'
@chakra-ui/react
'
;
import
{
chakra
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
{
LinkOverlay
}
from
'
toolkit/chakra/link
'
;
import
{
mediaStyleProps
}
from
'
./utils
'
;
import
{
mediaStyleProps
}
from
'
./utils
'
;
interface
Props
{
interface
Props
{
...
...
ui/showcases/Link.tsx
View file @
50676eb5
...
@@ -10,7 +10,7 @@ import * as blockMock from 'mocks/blocks/block';
...
@@ -10,7 +10,7 @@ import * as blockMock from 'mocks/blocks/block';
import
*
as
ensMock
from
'
mocks/ens/domain
'
;
import
*
as
ensMock
from
'
mocks/ens/domain
'
;
import
*
as
poolMock
from
'
mocks/pools/pool
'
;
import
*
as
poolMock
from
'
mocks/pools/pool
'
;
import
*
as
txMock
from
'
mocks/txs/tx
'
;
import
*
as
txMock
from
'
mocks/txs/tx
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
{
Link
,
LinkBox
,
LinkOverlay
}
from
'
toolkit/chakra/link
'
;
import
CutLinkDetails
from
'
toolkit/components/CutLink/CutLinkDetails
'
;
import
CutLinkDetails
from
'
toolkit/components/CutLink/CutLinkDetails
'
;
import
CutLinkList
from
'
toolkit/components/CutLink/CutLinkList
'
;
import
CutLinkList
from
'
toolkit/components/CutLink/CutLinkList
'
;
import
AddressEntity
from
'
ui/shared/entities/address/AddressEntity
'
;
import
AddressEntity
from
'
ui/shared/entities/address/AddressEntity
'
;
...
@@ -249,6 +249,22 @@ const LinkShowcase = () => {
...
@@ -249,6 +249,22 @@ const LinkShowcase = () => {
<
PoolEntity
pool=
{
poolMock
.
noIcons
}
isLoading
/>
<
PoolEntity
pool=
{
poolMock
.
noIcons
}
isLoading
/>
</
Sample
>
</
Sample
>
</
SamplesStack
>
</
SamplesStack
>
<
SectionSubHeader
>
Link overlay
</
SectionSubHeader
>
<
SamplesStack
>
<
Sample
label=
"Internal link"
>
<
LinkBox
p=
{
2
}
display=
"flex"
flexDirection=
"column"
columnGap=
{
2
}
borderWidth=
"1px"
borderColor=
"border.divider"
borderRadius=
"base"
>
<
LinkOverlay
href=
"/blocks"
>
Main link
</
LinkOverlay
>
<
Link
href=
"/txs"
>
Inner link
</
Link
>
</
LinkBox
>
</
Sample
>
<
Sample
label=
"External link"
>
<
LinkBox
p=
{
2
}
display=
"flex"
flexDirection=
"column"
columnGap=
{
2
}
borderWidth=
"1px"
borderColor=
"border.divider"
borderRadius=
"base"
>
<
LinkOverlay
href=
"https://blockscout.com"
external
>
Main link
</
LinkOverlay
>
<
Link
href=
"https://blockscout.com/txs"
external
>
Inner link
</
Link
>
</
LinkBox
>
</
Sample
>
</
SamplesStack
>
</
Section
>
</
Section
>
</
Container
>
</
Container
>
);
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment