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
730d6ddb
Commit
730d6ddb
authored
Jan 30, 2025
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
block details tab
parent
34f281d3
Changes
33
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
33 changed files
with
568 additions
and
653 deletions
+568
-653
.env.celo_alfajores
configs/envs/.env.celo_alfajores
+12
-7
eslint.config.mjs
eslint.config.mjs
+2
-1
[height_or_hash].tsx
pages/block/[height_or_hash].tsx
+2
-2
alert.tsx
toolkit/chakra/alert.tsx
+27
-22
badge.tsx
toolkit/chakra/badge.tsx
+2
-2
icon-button.tsx
toolkit/chakra/icon-button.tsx
+3
-1
tooltip.tsx
toolkit/chakra/tooltip.tsx
+4
-1
CutLink.tsx
toolkit/components/CutLink/CutLink.tsx
+15
-15
RoutedTabsSkeleton.tsx
toolkit/components/RoutedTabs/RoutedTabsSkeleton.tsx
+19
-12
alert.recipe.ts
toolkit/theme/recipes/alert.recipe.ts
+33
-8
badge.recipe.ts
toolkit/theme/recipes/badge.recipe.ts
+11
-0
AddressCsvExportLink.tsx
ui/address/AddressCsvExportLink.tsx
+10
-13
BlockCeloEpochTag.tsx
ui/block/BlockCeloEpochTag.tsx
+12
-28
BlockDetails.tsx
ui/block/BlockDetails.tsx
+221
-246
BlockDetailsBaseFeeCelo.tsx
ui/block/details/BlockDetailsBaseFeeCelo.tsx
+4
-6
BlockDetailsBlobInfo.tsx
ui/block/details/BlockDetailsBlobInfo.tsx
+5
-4
Block.tsx
ui/pages/Block.tsx
+45
-41
DetailsInfoItem.tsx
ui/shared/DetailsInfoItem.tsx
+7
-11
DetailsTimestamp.tsx
ui/shared/DetailsTimestamp.tsx
+3
-3
Hint.tsx
ui/shared/Hint.tsx
+1
-0
HintPopover.tsx
ui/shared/HintPopover.tsx
+0
-57
ListItemMobileGrid.tsx
ui/shared/ListItemMobile/ListItemMobileGrid.tsx
+5
-10
NetworkExplorers.tsx
ui/shared/NetworkExplorers.tsx
+7
-12
PopoverTriggerTooltip.tsx
ui/shared/PopoverTriggerTooltip.tsx
+0
-31
PrevNext.tsx
ui/shared/PrevNext.tsx
+26
-18
RawDataSnippet.tsx
ui/shared/RawDataSnippet.tsx
+7
-7
VerifyWith.tsx
ui/shared/VerifyWith.tsx
+28
-41
ServiceDegradationWarning.tsx
ui/shared/alerts/ServiceDegradationWarning.tsx
+10
-8
OptimisticL2TxnBatchDA.tsx
ui/shared/batch/OptimisticL2TxnBatchDA.tsx
+3
-3
VerificationSteps.tsx
ui/shared/verificationSteps/VerificationSteps.tsx
+2
-2
Alerts.tsx
ui/showcases/Alerts.tsx
+37
-36
Links.tsx
ui/showcases/Links.tsx
+1
-1
ZkSyncL2TxnBatchHashesInfo.tsx
ui/txnBatches/zkSyncL2/ZkSyncL2TxnBatchHashesInfo.tsx
+4
-4
No files found.
configs/envs/.env.celo_alfajores
View file @
730d6ddb
...
...
@@ -9,18 +9,21 @@ NEXT_PUBLIC_APP_PORT=3000
NEXT_PUBLIC_APP_ENV=development
NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL=ws
NEXT_PUBLIC_CELO_ENABLED=true
NEXT_PUBLIC_CELO_L2_UPGRADE_BLOCK=26369280
# Instance ENVs
NEXT_PUBLIC_ADMIN_SERVICE_API_HOST=https://admin-rs.services.blockscout.com
NEXT_PUBLIC_API_BASE_PATH=/
NEXT_PUBLIC_API_HOST=celo-alfajores.blockscout.com
NEXT_PUBLIC_API_SPEC_URL=https://raw.githubusercontent.com/blockscout/blockscout-api-v2-swagger/main/swagger.yaml
NEXT_PUBLIC_CELO_ENABLED=true
NEXT_PUBLIC_CELO_L2_UPGRADE_BLOCK=26369280
NEXT_PUBLIC_CONTRACT_CODE_IDES=[{'title':'Remix IDE','url':'https://remix.ethereum.org/?address={hash}&blockscout={domain}','icon_url':'https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/ide-icons/remix.png'}]
NEXT_PUBLIC_CONTRACT_INFO_API_HOST=https://contracts-info.services.blockscout.com
NEXT_PUBLIC_FEATURED_NETWORKS=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/featured-networks/celo-alfajores-testnet.json
NEXT_PUBLIC_GAME_BADGE_CLAIM_LINK=https://badges.blockscout.com/mint/sherblockHolmesBadge
NEXT_PUBLIC_GAS_TRACKER_ENABLED=false
NEXT_PUBLIC_GRAPHIQL_TRANSACTION=0x9767ce30754afad2a3279b9df2d13257f467c3dad4e0e601271e66d16dfd1641
NEXT_PUBLIC_HOMEPAGE_CHARTS=['daily_txs']
NEXT_PUBLIC_HOMEPAGE_PLATE_BACKGROUND=rgba(252, 255, 82, 1)
NEXT_PUBLIC_HOMEPAGE_PLATE_TEXT_COLOR=rgba(0, 0, 0, 1)
NEXT_PUBLIC_HOMEPAGE_HERO_BANNER_CONFIG={'background':['rgba(252, 255, 82, 1)'],'text_color':['rgba(0, 0, 0, 1)']}
NEXT_PUBLIC_IS_TESTNET=true
NEXT_PUBLIC_MARKETPLACE_ENABLED=false
NEXT_PUBLIC_METADATA_SERVICE_API_HOST=https://metadata.services.blockscout.com
...
...
@@ -32,12 +35,14 @@ NEXT_PUBLIC_NETWORK_ICON_DARK=https://raw.githubusercontent.com/blockscout/front
NEXT_PUBLIC_NETWORK_ID=44787
NEXT_PUBLIC_NETWORK_LOGO=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/celo-logo-light.svg
NEXT_PUBLIC_NETWORK_LOGO_DARK=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/network-logos/celo-logo-dark.svg
NEXT_PUBLIC_NETWORK_MULTIPLE_GAS_CURRENCIES=true
NEXT_PUBLIC_NETWORK_NAME=Celo Alfajores
NEXT_PUBLIC_NETWORK_RPC_URL=https://alfajores-forno.celo-testnet.org
NEXT_PUBLIC_NETWORK_SHORT_NAME=Alfajores
NEXT_PUBLIC_OG_ENHANCED_DATA_ENABLED=true
NEXT_PUBLIC_OG_IMAGE_URL=https://raw.githubusercontent.com/blockscout/frontend-configs/main/configs/og-images/celo.png
NEXT_PUBLIC_STATS_API_HOST=https://stats-alfajores-testnet.k8s-prod-1.blockscout.com
NEXT_PUBLIC_TRANSACTION_INTERPRETATION_PROVIDER=blockscout
NEXT_PUBLIC_VIEWS_BLOCK_HIDDEN_FIELDS=['burnt_fees']
NEXT_PUBLIC_VIEWS_CONTRACT_SOLIDITYSCAN_ENABLED=true
NEXT_PUBLIC_VISUALIZE_API_HOST=https://visualizer.services.blockscout.com
NEXT_PUBLIC_HOMEPAGE_STATS=['total_blocks','average_block_time','total_txs','wallet_addresses','gas_tracker','current_epoch']
\ No newline at end of file
NEXT_PUBLIC_VISUALIZE_API_HOST=https://visualizer.services.blockscout.com
\ No newline at end of file
eslint.config.mjs
View file @
730d6ddb
...
...
@@ -26,10 +26,11 @@ const RESTRICTED_MODULES = {
{
name
:
'
@metamask/post-message-stream
'
,
message
:
'
Please lazy-load @metamask/post-message-stream or use useProvider hook instead
'
},
{
name
:
'
playwright/TestApp
'
,
message
:
'
Please use render() fixture from test() function of playwright/lib module
'
},
{
name
:
'
ui/shared/chakra/Skeleton
'
,
message
:
'
Please use Skeleton component from toolkit/chakra instead
'
},
{
name
:
'
ui/shared/Tabs/RoutedTabs
'
,
message
:
'
Please use RoutedTabs component from toolkit/components/RoutedTabs instead
'
},
{
name
:
'
@chakra-ui/react
'
,
importNames
:
[
'
Menu
'
,
'
useToast
'
,
'
useDisclosure
'
,
'
useClipboard
'
,
'
Tooltip
'
,
'
Skeleton
'
,
'
IconButton
'
,
'
Button
'
,
'
Link
'
,
'
Menu
'
,
'
useToast
'
,
'
useDisclosure
'
,
'
useClipboard
'
,
'
Tooltip
'
,
'
Skeleton
'
,
'
IconButton
'
,
'
Button
'
,
'
Link
'
,
'
Tag
'
,
'
Image
'
,
'
Popover
'
,
'
PopoverTrigger
'
,
'
PopoverContent
'
,
'
PopoverBody
'
,
'
PopoverFooter
'
,
'
DrawerRoot
'
,
'
DrawerBody
'
,
'
DrawerContent
'
,
'
DrawerOverlay
'
,
'
DrawerBackdrop
'
,
'
DrawerTrigger
'
,
'
Drawer
'
,
'
Alert
'
,
'
AlertIcon
'
,
'
AlertTitle
'
,
'
AlertDescription
'
,
...
...
pages/block/[height_or_hash].tsx
View file @
730d6ddb
...
...
@@ -5,12 +5,12 @@ import React from 'react';
import
type
{
Props
}
from
'
nextjs/getServerSideProps
'
;
import
PageNextJs
from
'
nextjs/PageNextJs
'
;
//
const Block = dynamic(() => import('ui/pages/Block'), { ssr: false });
const
Block
=
dynamic
(()
=>
import
(
'
ui/pages/Block
'
),
{
ssr
:
false
});
const
Page
:
NextPage
<
Props
>
=
(
props
:
Props
)
=>
{
return
(
<
PageNextJs
pathname=
"/block/[height_or_hash]"
query=
{
props
.
query
}
>
{
/* <Block/> */
}
<
Block
/>
</
PageNextJs
>
);
};
...
...
toolkit/chakra/alert.tsx
View file @
730d6ddb
...
...
@@ -4,6 +4,7 @@ import * as React from 'react';
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
{
CloseButton
}
from
'
./close-button
'
;
import
{
Skeleton
}
from
'
./skeleton
'
;
export
interface
AlertProps
extends
Omit
<
ChakraAlert
.
RootProps
,
'
title
'
>
{
startElement
?:
React
.
ReactNode
;
...
...
@@ -12,6 +13,7 @@ export interface AlertProps extends Omit<ChakraAlert.RootProps, 'title'> {
icon
?:
React
.
ReactElement
;
closable
?:
boolean
;
onClose
?:
()
=>
void
;
loading
?:
boolean
;
}
export
const
Alert
=
React
.
forwardRef
<
HTMLDivElement
,
AlertProps
>
(
...
...
@@ -24,33 +26,36 @@ export const Alert = React.forwardRef<HTMLDivElement, AlertProps>(
onClose
,
startElement
,
endElement
,
loading
,
...
rest
}
=
props
;
const
defaultIcon
=
<
IconSvg
name=
"info_filled"
/>;
const
defaultIcon
=
<
IconSvg
name=
"info_filled"
w=
"100%"
h=
"100%"
/>;
return
(
<
ChakraAlert
.
Root
ref=
{
ref
}
{
...
rest
}
>
{
startElement
!==
undefined
||
icon
!==
undefined
?
startElement
:
<
ChakraAlert
.
Indicator
>
{
icon
||
defaultIcon
}
</
ChakraAlert
.
Indicator
>
}
{
children
?
(
<
ChakraAlert
.
Content
>
{
title
&&
<
ChakraAlert
.
Title
>
{
title
}
</
ChakraAlert
.
Title
>
}
<
ChakraAlert
.
Description
display=
"inline-flex"
>
{
children
}
</
ChakraAlert
.
Description
>
</
ChakraAlert
.
Content
>
)
:
(
<
ChakraAlert
.
Title
flex=
"1"
>
{
title
}
</
ChakraAlert
.
Title
>
)
}
{
endElement
}
{
closable
&&
(
<
CloseButton
pos=
"relative"
top=
"-2"
insetEnd=
"-2"
alignSelf=
"flex-start"
onClick=
{
onClose
}
/>
)
}
</
ChakraAlert
.
Root
>
<
Skeleton
loading=
{
loading
}
asChild
>
<
ChakraAlert
.
Root
ref=
{
ref
}
{
...
rest
}
>
{
startElement
!==
undefined
||
icon
!==
undefined
?
startElement
:
<
ChakraAlert
.
Indicator
>
{
icon
||
defaultIcon
}
</
ChakraAlert
.
Indicator
>
}
{
children
?
(
<
ChakraAlert
.
Content
>
{
title
&&
<
ChakraAlert
.
Title
>
{
title
}
</
ChakraAlert
.
Title
>
}
<
ChakraAlert
.
Description
display=
"inline-flex"
>
{
children
}
</
ChakraAlert
.
Description
>
</
ChakraAlert
.
Content
>
)
:
(
<
ChakraAlert
.
Title
flex=
"1"
>
{
title
}
</
ChakraAlert
.
Title
>
)
}
{
endElement
}
{
closable
&&
(
<
CloseButton
pos=
"relative"
top=
"-2"
insetEnd=
"-2"
alignSelf=
"flex-start"
onClick=
{
onClose
}
/>
)
}
</
ChakraAlert
.
Root
>
</
Skeleton
>
);
},
);
toolkit/chakra/badge.tsx
View file @
730d6ddb
...
...
@@ -14,10 +14,10 @@ export interface BadgeProps extends ChakraBadgeProps {
export
const
Badge
=
React
.
forwardRef
<
HTMLSpanElement
,
BadgeProps
>
(
function
Badge
(
props
,
ref
)
{
const
{
loading
,
iconStart
,
children
,
...
rest
}
=
props
;
const
{
loading
,
iconStart
,
children
,
asChild
=
true
,
...
rest
}
=
props
;
return
(
<
Skeleton
loading=
{
loading
}
>
<
Skeleton
loading=
{
loading
}
asChild=
{
asChild
}
>
<
ChakraBadge
ref=
{
ref
}
display=
"flex"
alignItems=
"center"
gap=
{
1
}
{
...
rest
}
>
{
iconStart
&&
<
IconSvg
name=
{
iconStart
}
boxSize=
"10px"
/>
}
{
children
}
...
...
toolkit/chakra/icon-button.tsx
View file @
730d6ddb
...
...
@@ -5,12 +5,14 @@ import { Skeleton } from './skeleton';
export
interface
IconButtonProps
extends
ButtonProps
{}
// TODO @tom2drum variants for icon buttons: prev-next, top-bar, copy-to-clipboard
export
const
IconButton
=
React
.
forwardRef
<
HTMLDivElement
,
IconButtonProps
>
(
function
IconButton
(
props
,
ref
)
{
const
{
loading
,
size
,
variant
=
'
plain
'
,
...
rest
}
=
props
;
return
(
<
Skeleton
loading=
{
loading
}
ref=
{
ref
}
>
<
Skeleton
loading=
{
loading
}
ref=
{
ref
}
asChild
>
<
Button
display=
"inline-flex"
px=
"0"
...
...
toolkit/chakra/tooltip.tsx
View file @
730d6ddb
...
...
@@ -12,6 +12,7 @@ export interface TooltipProps extends ChakraTooltip.RootProps {
content
:
React
.
ReactNode
;
contentProps
?:
ChakraTooltip
.
ContentProps
;
disabled
?:
boolean
;
disableOnMobile
?:
boolean
;
}
export
const
Tooltip
=
React
.
forwardRef
<
HTMLDivElement
,
TooltipProps
>
(
...
...
@@ -23,6 +24,7 @@ export const Tooltip = React.forwardRef<HTMLDivElement, TooltipProps>(
selected
,
children
,
disabled
,
disableOnMobile
,
portalled
=
true
,
content
,
contentProps
,
...
...
@@ -36,6 +38,7 @@ export const Tooltip = React.forwardRef<HTMLDivElement, TooltipProps>(
const
[
open
,
setOpen
]
=
React
.
useState
(
defaultOpen
);
const
isMobile
=
useIsMobile
();
// TODO @tom2drum merge refs
const
triggerRef
=
useClickAway
<
HTMLButtonElement
>
(()
=>
setOpen
(
false
));
const
handleOpenChange
=
React
.
useCallback
((
details
:
{
open
:
boolean
})
=>
{
...
...
@@ -47,7 +50,7 @@ export const Tooltip = React.forwardRef<HTMLDivElement, TooltipProps>(
setOpen
((
prev
)
=>
!
prev
);
},
[
]);
if
(
disabled
)
return
children
;
if
(
disabled
||
(
disableOnMobile
&&
isMobile
)
)
return
children
;
const
defaultShowArrow
=
visual
===
'
popover
'
?
false
:
true
;
const
showArrow
=
showArrowProp
!==
undefined
?
showArrowProp
:
defaultShowArrow
;
...
...
toolkit/components/CutLink/CutLink.tsx
View file @
730d6ddb
import
React
from
'
react
'
;
import
{
scroller
,
Element
}
from
'
react-scroll
'
;
import
type
{
LinkProps
}
from
'
toolkit/chakra/link
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
interface
Props
{
interface
Props
extends
LinkProps
{
children
:
React
.
ReactNode
;
id
?:
string
;
onClick
?:
()
=>
void
;
isLoading
?:
boolean
;
}
const
ID
=
'
CutLink
'
;
const
CutLink
=
(
props
:
Props
)
=>
{
const
{
children
,
id
=
ID
,
onClick
,
isLoading
}
=
props
;
const
{
children
,
id
=
ID
,
onClick
,
...
rest
}
=
props
;
const
[
isExpanded
,
setIsExpanded
]
=
React
.
useState
(
false
);
...
...
@@ -27,19 +26,20 @@ const CutLink = (props: Props) => {
onClick
?.();
},
[
id
,
onClick
]);
const
text
=
isExpanded
?
'
Hide details
'
:
'
View details
'
;
return
(
<>
<
Element
name=
{
id
}
>
<
Link
textStyle=
"sm"
textDecorationLine=
"underline"
textDecorationStyle=
"dashed"
onClick=
{
handleClick
}
loading=
{
isLoading
}
>
{
isExpanded
?
'
Hide details
'
:
'
View details
'
}
</
Link
>
</
Element
>
<
Link
textStyle=
"sm"
textDecorationLine=
"underline"
textDecorationStyle=
"dashed"
onClick=
{
handleClick
}
asChild
{
...
rest
}
>
<
Element
name=
{
id
}
>
{
text
}
</
Element
>
</
Link
>
{
isExpanded
&&
children
}
</>
);
...
...
ui/shared/Tabs/
TabsSkeleton.tsx
→
toolkit/components/RoutedTabs/Routed
TabsSkeleton.tsx
View file @
730d6ddb
import
{
Flex
,
chakra
,
Box
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
{
Flex
,
chakra
,
Box
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
RoutedTab
}
from
'
../
Tabs/types
'
;
import
type
{
TabItemRegular
}
from
'
../Adaptive
Tabs/types
'
;
import
Skeleton
from
'
ui/shared/chakra/S
keleton
'
;
import
useTabIndexFromQuery
from
'
ui/shared/Tabs/useTabIndexFromQuery
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/s
keleton
'
;
import
type
{
TabsProps
}
from
'
toolkit/chakra/tabs
'
;
type
TabSize
=
'
sm
'
|
'
md
'
;
import
useActiveTabFromQuery
from
'
./useActiveTabFromQuery
'
;
const
SkeletonTabText
=
({
size
,
title
}:
{
size
:
Tab
Size
;
title
:
RoutedTab
[
'
title
'
]
})
=>
(
const
SkeletonTabText
=
({
size
,
title
}:
{
size
:
Tab
sProps
[
'
size
'
];
title
:
TabItemRegular
[
'
title
'
]
})
=>
(
<
Skeleton
borderRadius=
"base"
borderWidth=
{
size
===
'
sm
'
?
'
2px
'
:
0
}
...
...
@@ -22,18 +22,19 @@ const SkeletonTabText = ({ size, title }: { size: TabSize; title: RoutedTab['tit
interface
Props
{
className
?:
string
;
tabs
:
Array
<
RoutedTab
>
;
tabs
:
Array
<
TabItemRegular
>
;
size
?:
'
sm
'
|
'
md
'
;
}
const
TabsSkeleton
=
({
className
,
tabs
,
size
=
'
md
'
}:
Props
)
=>
{
const
bgColor
=
useColorModeValue
(
'
blackAlpha.50
'
,
'
whiteAlpha.50
'
);
const
tabIndex
=
useTabIndexFromQuery
(
tabs
||
[]);
const
RoutedTabsSkeleton
=
({
className
,
tabs
,
size
=
'
md
'
}:
Props
)
=>
{
const
activeTab
=
useActiveTabFromQuery
(
tabs
);
if
(
tabs
.
length
===
1
)
{
return
null
;
}
const
tabIndex
=
activeTab
?
tabs
.
findIndex
((
tab
)
=>
tab
.
id
===
activeTab
.
id
)
:
0
;
return
(
<
Flex
className=
{
className
}
my=
{
8
}
alignItems=
"center"
overflow=
"hidden"
>
{
tabs
.
slice
(
0
,
tabIndex
).
map
(({
title
,
id
})
=>
(
...
...
@@ -44,7 +45,13 @@ const TabsSkeleton = ({ className, tabs, size = 'md' }: Props) => {
/>
))
}
{
tabs
.
slice
(
tabIndex
,
tabIndex
+
1
).
map
(({
title
,
id
})
=>
(
<
Box
key=
{
id
.
toString
()
}
bgColor=
{
bgColor
}
py=
{
size
===
'
sm
'
?
1
:
2
}
borderRadius=
"base"
flexShrink=
{
0
}
>
<
Box
key=
{
id
.
toString
()
}
bgColor=
{
{
_light
:
'
blackAlpha.50
'
,
_dark
:
'
whiteAlpha.50
'
}
}
py=
{
size
===
'
sm
'
?
1
:
2
}
borderRadius=
"base"
flexShrink=
{
0
}
>
<
SkeletonTabText
key=
{
id
.
toString
()
}
title=
{
title
}
...
...
@@ -63,4 +70,4 @@ const TabsSkeleton = ({ className, tabs, size = 'md' }: Props) => {
);
};
export
default
chakra
(
TabsSkeleton
);
export
default
chakra
(
Routed
TabsSkeleton
);
toolkit/theme/recipes/alert.recipe.ts
View file @
730d6ddb
...
...
@@ -27,6 +27,7 @@ export const recipe = defineSlotRecipe({
height
:
'
5
'
,
_icon
:
{
boxSize
:
'
full
'
},
color
:
'
alert.fg
'
,
'
--layer-bg
'
:
'
transparent
'
,
},
content
:
{
display
:
'
flex
'
,
...
...
@@ -35,24 +36,48 @@ export const recipe = defineSlotRecipe({
},
variants
:
{
visual
:
{
status
:
{
info
:
{
root
:
{
bg
:
'
alert.bg.info
'
,
color
:
'
alert.fg
'
},
root
:
{
bg
:
'
alert.bg.info
'
,
'
--layer-bg
'
:
'
{colors.alert.bg.info}
'
,
color
:
'
alert.fg
'
,
},
},
warning
:
{
root
:
{
bg
:
'
alert.bg.warning
'
,
color
:
'
alert.fg
'
},
root
:
{
bg
:
'
alert.bg.warning
'
,
'
--layer-bg
'
:
'
{colors.alert.bg.warning}
'
,
color
:
'
alert.fg
'
,
},
},
warning_table
:
{
root
:
{
bg
:
'
alert.bg.warning_table
'
,
color
:
'
alert.fg
'
},
root
:
{
bg
:
'
alert.bg.warning_table
'
,
'
--layer-bg
'
:
'
{colors.alert.bg.warning_table}
'
,
color
:
'
alert.fg
'
,
},
},
success
:
{
root
:
{
bg
:
'
alert.bg.success
'
,
color
:
'
alert.fg
'
},
root
:
{
bg
:
'
alert.bg.success
'
,
'
--layer-bg
'
:
'
{colors.alert.bg.success}
'
,
color
:
'
alert.fg
'
,
},
},
error
:
{
root
:
{
bg
:
'
alert.bg.error
'
,
color
:
'
alert.fg
'
},
root
:
{
bg
:
'
alert.bg.error
'
,
'
--layer-bg
'
:
'
{colors.alert.bg.error}
'
,
color
:
'
alert.fg
'
,
},
},
neutral
:
{
root
:
{
bg
:
'
alert.bg.neutral
'
,
color
:
'
alert.fg
'
},
root
:
{
bg
:
'
alert.bg.neutral
'
,
'
--layer-bg
'
:
'
{colors.alert.bg.neutral}
'
,
color
:
'
alert.fg
'
,
},
},
},
...
...
@@ -92,7 +117,7 @@ export const recipe = defineSlotRecipe({
},
defaultVariants
:
{
visual
:
'
neutral
'
,
status
:
'
neutral
'
,
size
:
'
md
'
,
inline
:
true
,
},
...
...
toolkit/theme/recipes/badge.recipe.ts
View file @
730d6ddb
...
...
@@ -17,46 +17,57 @@ export const recipe = defineRecipe({
colorPalette
:
{
gray
:
{
bg
:
'
badge.gray.bg
'
,
'
--layer-bg
'
:
'
{colors.badge.gray.bg}
'
,
color
:
'
badge.gray.fg
'
,
},
green
:
{
bg
:
'
badge.green.bg
'
,
'
--layer-bg
'
:
'
{colors.badge.green.bg}
'
,
color
:
'
badge.green.fg
'
,
},
red
:
{
bg
:
'
badge.red.bg
'
,
'
--layer-bg
'
:
'
{colors.badge.red.bg}
'
,
color
:
'
badge.red.fg
'
,
},
purple
:
{
bg
:
'
badge.purple.bg
'
,
'
--layer-bg
'
:
'
{colors.badge.purple.bg}
'
,
color
:
'
badge.purple.fg
'
,
},
orange
:
{
bg
:
'
badge.orange.bg
'
,
'
--layer-bg
'
:
'
{colors.badge.orange.bg}
'
,
color
:
'
badge.orange.fg
'
,
},
blue
:
{
bg
:
'
badge.blue.bg
'
,
'
--layer-bg
'
:
'
{colors.badge.blue.bg}
'
,
color
:
'
badge.blue.fg
'
,
},
yellow
:
{
bg
:
'
badge.yellow.bg
'
,
'
--layer-bg
'
:
'
{colors.badge.yellow.bg}
'
,
color
:
'
badge.yellow.fg
'
,
},
teal
:
{
bg
:
'
badge.teal.bg
'
,
'
--layer-bg
'
:
'
{colors.badge.teal.bg}
'
,
color
:
'
badge.teal.fg
'
,
},
cyan
:
{
bg
:
'
badge.cyan.bg
'
,
'
--layer-bg
'
:
'
{colors.badge.cyan.bg}
'
,
color
:
'
badge.cyan.fg
'
,
},
purple_alt
:
{
bg
:
'
badge.purple_alt.bg
'
,
'
--layer-bg
'
:
'
{colors.badge.purple_alt.bg}
'
,
color
:
'
badge.purple_alt.fg
'
,
},
blue_alt
:
{
bg
:
'
badge.blue_alt.bg
'
,
'
--layer-bg
'
:
'
{colors.badge.blue_alt.bg}
'
,
color
:
'
badge.blue_alt.fg
'
,
},
},
...
...
ui/address/AddressCsvExportLink.tsx
View file @
730d6ddb
import
{
chakra
,
Tooltip
,
Hide
,
Flex
}
from
'
@chakra-ui/react
'
;
import
{
chakra
,
Flex
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
CsvExportParams
}
from
'
types/client/address
'
;
...
...
@@ -8,9 +8,10 @@ import { route } from 'nextjs-routes';
import
config
from
'
configs/app
'
;
import
useIsInitialLoading
from
'
lib/hooks/useIsInitialLoading
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
{
Tooltip
}
from
'
toolkit/chakra/tooltip
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
LinkInternal
from
'
ui/shared/links/LinkInternal
'
;
interface
Props
{
address
:
string
;
...
...
@@ -30,27 +31,23 @@ const AddressCsvExportLink = ({ className, address, params, isLoading }: Props)
if
(
isInitialLoading
)
{
return
(
<
Flex
className=
{
className
}
flexShrink=
{
0
}
alignItems=
"center"
>
<
Skeleton
boxSize=
{
{
base
:
'
32px
'
,
lg
:
6
}
}
borderRadius=
"base"
/>
<
Hide
ssr=
{
false
}
below=
"lg"
>
<
Skeleton
w=
"112px"
h=
{
6
}
ml=
{
1
}
/>
</
Hide
>
<
Skeleton
boxSize=
{
{
base
:
8
,
lg
:
6
}
}
/>
<
Skeleton
loading
hideBelow=
"lg"
w=
"112px"
h=
{
6
}
ml=
{
1
}
/>
</
Flex
>
);
}
return
(
<
Tooltip
isDisabled=
{
!
isMobile
}
label
=
"Download CSV"
>
<
Link
Internal
<
Tooltip
disabled=
{
!
isMobile
}
content
=
"Download CSV"
>
<
Link
className=
{
className
}
display=
"inline-flex"
alignItems=
"center"
whiteSpace=
"nowrap"
href=
{
route
({
pathname
:
'
/csv-export
'
,
query
:
{
...
params
,
address
}
})
}
flexShrink=
{
0
}
>
<
IconSvg
name=
"files/csv"
boxSize=
{
{
base
:
'
30px
'
,
lg
:
6
}
}
/>
<
Hide
ssr=
{
false
}
below=
"lg"
><
chakra
.
span
ml=
{
1
}
>
Download CSV
</
chakra
.
span
></
Hide
>
</
Link
Internal
>
<
chakra
.
span
ml=
{
1
}
hideBelow=
"lg"
>
Download CSV
</
chakra
.
span
>
</
Link
>
</
Tooltip
>
);
};
...
...
ui/block/BlockCeloEpochTag.tsx
View file @
730d6ddb
import
{
Tag
,
Tooltip
,
useDisclosure
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
{
route
}
from
'
nextjs-routes
'
;
import
config
from
'
configs/app
'
;
import
LinkInternal
from
'
ui/shared/links/LinkInternal
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
{
Tag
}
from
'
toolkit/chakra/tag
'
;
import
{
Tooltip
}
from
'
toolkit/chakra/tooltip
'
;
import
type
{
BlockQuery
}
from
'
./useBlockQuery
'
;
...
...
@@ -13,9 +14,6 @@ interface Props {
}
const
BlockCeloEpochTag
=
({
blockQuery
}:
Props
)
=>
{
// have to implement controlled tooltip because of the issue - https://github.com/chakra-ui/chakra-ui/issues/7107
const
{
isOpen
,
onOpen
,
onToggle
,
onClose
}
=
useDisclosure
();
if
(
!
blockQuery
.
data
?.
celo
)
{
return
null
;
}
...
...
@@ -26,28 +24,19 @@ const BlockCeloEpochTag = ({ blockQuery }: Props) => {
blockQuery
.
data
.
celo
.
epoch_number
*
celoConfig
.
BLOCKS_PER_EPOCH
:
undefined
;
const
tag
=
(
<
Tag
colorScheme=
{
epochBlockNumber
?
'
gray-blue
'
:
'
gray
'
}
onClick=
{
epochBlockNumber
?
undefined
:
onToggle
}
onMouseEnter=
{
onOpen
}
onMouseLeave=
{
onClose
}
>
Epoch #
{
blockQuery
.
data
.
celo
.
epoch_number
}
</
Tag
>
// TODO @tom2drum revise tag color scheme
<
Tag
colorScheme=
{
epochBlockNumber
?
'
gray-blue
'
:
'
gray
'
}
>
Epoch #
{
blockQuery
.
data
.
celo
.
epoch_number
}
</
Tag
>
);
const
content
=
epochBlockNumber
?
(
<
Link
Internal
href=
{
route
({
pathname
:
'
/block/[height_or_hash]
'
,
query
:
{
height_or_hash
:
String
(
epochBlockNumber
)
}
})
}
>
<
Link
href=
{
route
({
pathname
:
'
/block/[height_or_hash]
'
,
query
:
{
height_or_hash
:
String
(
epochBlockNumber
)
}
})
}
>
{
tag
}
</
Link
Internal
>
</
Link
>
)
:
tag
;
return
(
<
Tooltip
label=
"Displays the epoch this block belongs to before the epoch is finalized"
maxW=
"280px"
textAlign=
"center"
isOpen=
{
isOpen
}
onClose=
{
onClose
}
key=
"epoch-tag-before-finalized"
content=
"Displays the epoch this block belongs to before the epoch is finalized"
>
{
content
}
</
Tooltip
>
...
...
@@ -56,15 +45,10 @@ const BlockCeloEpochTag = ({ blockQuery }: Props) => {
return
(
<
Tooltip
label=
"Displays the epoch finalized by this block"
maxW=
"280px"
textAlign=
"center"
isOpen=
{
isOpen
}
onClose=
{
onClose
}
key=
"epoch-tag"
content=
"Displays the epoch finalized by this block"
>
<
Tag
bgColor=
"celo"
color=
"blackAlpha.800"
onClick=
{
onToggle
}
onMouseEnter=
{
onOpen
}
onMouseLeave=
{
onClose
}
>
Finalized epoch #
{
blockQuery
.
data
.
celo
.
epoch_number
}
</
Tag
>
<
Tag
bgColor=
"celo"
color=
"blackAlpha.800"
>
Finalized epoch #
{
blockQuery
.
data
.
celo
.
epoch_number
}
</
Tag
>
</
Tooltip
>
);
};
...
...
ui/block/BlockDetails.tsx
View file @
730d6ddb
This diff is collapsed.
Click to expand it.
ui/block/details/BlockDetailsBaseFeeCelo.tsx
View file @
730d6ddb
import
{
Box
,
Flex
,
Link
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
Flex
}
from
'
@chakra-ui/react
'
;
import
BigNumber
from
'
bignumber.js
'
;
import
React
from
'
react
'
;
...
...
@@ -7,6 +7,7 @@ import type { BlockBaseFeeCelo } from 'types/api/block';
import
type
{
TokenInfo
}
from
'
types/api/token
'
;
import
{
WEI
,
ZERO_ADDRESS
}
from
'
lib/consts
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
AddressFromTo
from
'
ui/shared/address/AddressFromTo
'
;
import
*
as
DetailsInfoItem
from
'
ui/shared/DetailsInfoItem
'
;
import
DetailsInfoItemDivider
from
'
ui/shared/DetailsInfoItemDivider
'
;
...
...
@@ -50,7 +51,7 @@ const BlockDetailsBaseFeeCelo = ({ data }: Props) => {
const
totalFeeLabel
=
(
<
Box
whiteSpace=
"pre-wrap"
>
<
span
>
The FeeHandler regularly burns 80% of its tokens. Non-CELO tokens are swapped to CELO beforehand. The remaining 20% are sent to the
</
span
>
<
Link
isE
xternal
href=
"https://www.ultragreen.money"
>
Green Fund
</
Link
>
<
Link
e
xternal
href=
"https://www.ultragreen.money"
>
Green Fund
</
Link
>
<
span
>
.
</
span
>
</
Box
>
);
...
...
@@ -65,10 +66,7 @@ const BlockDetailsBaseFeeCelo = ({ data }: Props) => {
<
DetailsInfoItem
.
Value
>
<
AddressEntity
address=
{
data
.
recipient
}
/>
</
DetailsInfoItem
.
Value
>
<
DetailsInfoItem
.
Label
hint=
{
totalFeeLabel
}
type=
"popover"
>
<
DetailsInfoItem
.
Label
hint=
{
totalFeeLabel
}
>
Base fee total
</
DetailsInfoItem
.
Label
>
<
DetailsInfoItem
.
Value
display=
"block"
>
...
...
ui/block/details/BlockDetailsBlobInfo.tsx
View file @
730d6ddb
import
{
Text
,
Tooltip
}
from
'
@chakra-ui/react
'
;
import
{
Text
}
from
'
@chakra-ui/react
'
;
import
BigNumber
from
'
bignumber.js
'
;
import
React
from
'
react
'
;
...
...
@@ -7,6 +7,7 @@ import type { Block } from 'types/api/block';
import
{
WEI
,
WEI_IN_GWEI
,
ZERO
}
from
'
lib/consts
'
;
import
{
space
}
from
'
lib/html-entities
'
;
import
{
currencyUnits
}
from
'
lib/units
'
;
import
{
Tooltip
}
from
'
toolkit/chakra/tooltip
'
;
import
*
as
DetailsInfoItem
from
'
ui/shared/DetailsInfoItem
'
;
import
DetailsInfoItemDivider
from
'
ui/shared/DetailsInfoItemDivider
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
...
...
@@ -42,7 +43,7 @@ const BlockDetailsBlobInfo = ({ data }: Props) => {
</
DetailsInfoItem
.
Label
>
<
DetailsInfoItem
.
Value
>
<
Text
>
{
BigNumber
(
data
.
blob_gas_price
).
dividedBy
(
WEI
).
toFixed
()
}
{
currencyUnits
.
ether
}
</
Text
>
<
Text
variant=
"
secondary"
whiteSpace=
"pre"
>
<
Text
color=
"text.
secondary"
whiteSpace=
"pre"
>
{
space
}
(
{
BigNumber
(
data
.
blob_gas_price
).
dividedBy
(
WEI_IN_GWEI
).
toFixed
()
}
{
currencyUnits
.
gwei
}
)
</
Text
>
</
DetailsInfoItem
.
Value
>
...
...
@@ -71,7 +72,7 @@ const BlockDetailsBlobInfo = ({ data }: Props) => {
<
IconSvg
name=
"flame"
boxSize=
{
5
}
color=
"gray.500"
mr=
{
2
}
/>
{
burntBlobFees
.
dividedBy
(
WEI
).
toFixed
()
}
{
currencyUnits
.
ether
}
{
!
blobFees
.
isEqualTo
(
ZERO
)
&&
(
<
Tooltip
label
=
"Blob burnt fees / Txn fees * 100%"
>
<
Tooltip
content
=
"Blob burnt fees / Txn fees * 100%"
>
<
div
>
<
Utilization
ml=
{
4
}
value=
{
burntBlobFees
.
dividedBy
(
blobFees
).
toNumber
()
}
/>
</
div
>
...
...
@@ -89,7 +90,7 @@ const BlockDetailsBlobInfo = ({ data }: Props) => {
</
DetailsInfoItem
.
Label
>
<
DetailsInfoItem
.
Value
>
<
Text
>
{
BigNumber
(
data
.
excess_blob_gas
).
dividedBy
(
WEI
).
toFixed
()
}
{
currencyUnits
.
ether
}
</
Text
>
<
Text
variant=
"
secondary"
whiteSpace=
"pre"
>
<
Text
color=
"text.
secondary"
whiteSpace=
"pre"
>
{
space
}
(
{
BigNumber
(
data
.
excess_blob_gas
).
dividedBy
(
WEI_IN_GWEI
).
toFixed
()
}
{
currencyUnits
.
gwei
}
)
</
Text
>
</
DetailsInfoItem
.
Value
>
...
...
ui/pages/Block.tsx
View file @
730d6ddb
...
...
@@ -13,6 +13,9 @@ import throwOnResourceLoadError from 'lib/errors/throwOnResourceLoadError';
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
getNetworkValidationActionText
from
'
lib/networks/getNetworkValidationActionText
'
;
import
getQueryParamString
from
'
lib/router/getQueryParamString
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
RoutedTabs
from
'
toolkit/components/RoutedTabs/RoutedTabs
'
;
import
RoutedTabsSkeleton
from
'
toolkit/components/RoutedTabs/RoutedTabsSkeleton
'
;
import
BlockCeloEpochTag
from
'
ui/block/BlockCeloEpochTag
'
;
import
BlockDetails
from
'
ui/block/BlockDetails
'
;
import
BlockEpochRewards
from
'
ui/block/BlockEpochRewards
'
;
...
...
@@ -23,13 +26,10 @@ import useBlockTxsQuery from 'ui/block/useBlockTxsQuery';
import
useBlockWithdrawalsQuery
from
'
ui/block/useBlockWithdrawalsQuery
'
;
import
TextAd
from
'
ui/shared/ad/TextAd
'
;
import
ServiceDegradationWarning
from
'
ui/shared/alerts/ServiceDegradationWarning
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
AddressEntity
from
'
ui/shared/entities/address/AddressEntity
'
;
import
NetworkExplorers
from
'
ui/shared/NetworkExplorers
'
;
import
PageTitle
from
'
ui/shared/Page/PageTitle
'
;
import
Pagination
from
'
ui/shared/pagination/Pagination
'
;
import
RoutedTabs
from
'
ui/shared/Tabs/RoutedTabs
'
;
import
TabsSkeleton
from
'
ui/shared/Tabs/TabsSkeleton
'
;
import
TxsWithFrontendSorting
from
'
ui/txs/TxsWithFrontendSorting
'
;
const
TAB_LIST_PROPS
=
{
...
...
@@ -68,40 +68,40 @@ const BlockPageContent = () => {
</>
),
},
{
id
:
'
txs
'
,
title
:
'
Transactions
'
,
component
:
(
<>
{
blockTxsQuery
.
isDegradedData
&&
<
ServiceDegradationWarning
isLoading=
{
blockTxsQuery
.
isPlaceholderData
}
mb=
{
6
}
/>
}
<
TxsWithFrontendSorting
query=
{
blockTxsQuery
}
showBlockInfo=
{
false
}
showSocketInfo=
{
false
}
top=
{
hasPagination
?
TABS_HEIGHT
:
0
}
/>
</>
),
},
config
.
features
.
dataAvailability
.
isEnabled
&&
blockQuery
.
data
?.
blob_transaction_count
?
{
id
:
'
blob_txs
'
,
title
:
'
Blob txns
'
,
component
:
(
<
TxsWithFrontendSorting
query=
{
blockBlobTxsQuery
}
showBlockInfo=
{
false
}
showSocketInfo=
{
false
}
/>
),
}
:
null
,
config
.
features
.
beaconChain
.
isEnabled
&&
Boolean
(
blockQuery
.
data
?.
withdrawals_count
)
?
{
id
:
'
withdrawals
'
,
title
:
'
Withdrawals
'
,
component
:
(
<>
{
blockWithdrawalsQuery
.
isDegradedData
&&
<
ServiceDegradationWarning
isLoading=
{
blockWithdrawalsQuery
.
isPlaceholderData
}
mb=
{
6
}
/>
}
<
BlockWithdrawals
blockWithdrawalsQuery=
{
blockWithdrawalsQuery
}
/>
</>
),
}
:
null
,
blockQuery
.
data
?.
celo
?.
is_epoch_block
?
{
id
:
'
epoch_rewards
'
,
title
:
'
Epoch rewards
'
,
component
:
<
BlockEpochRewards
heightOrHash=
{
heightOrHash
}
/>,
}
:
null
,
//
{
//
id: 'txs',
//
title: 'Transactions',
//
component: (
//
<>
//
{ blockTxsQuery.isDegradedData && <ServiceDegradationWarning isLoading={ blockTxsQuery.isPlaceholderData } mb={ 6 }/> }
//
<TxsWithFrontendSorting query={ blockTxsQuery } showBlockInfo={ false } showSocketInfo={ false } top={ hasPagination ? TABS_HEIGHT : 0 }/>
//
</>
//
),
//
},
//
config.features.dataAvailability.isEnabled && blockQuery.data?.blob_transaction_count ?
//
{
//
id: 'blob_txs',
//
title: 'Blob txns',
//
component: (
//
<TxsWithFrontendSorting query={ blockBlobTxsQuery } showBlockInfo={ false } showSocketInfo={ false }/>
//
),
//
} : null,
//
config.features.beaconChain.isEnabled && Boolean(blockQuery.data?.withdrawals_count) ?
//
{
//
id: 'withdrawals',
//
title: 'Withdrawals',
//
component: (
//
<>
//
{ blockWithdrawalsQuery.isDegradedData && <ServiceDegradationWarning isLoading={ blockWithdrawalsQuery.isPlaceholderData } mb={ 6 }/> }
//
<BlockWithdrawals blockWithdrawalsQuery={ blockWithdrawalsQuery }/>
//
</>
//
),
//
} : null,
//
blockQuery.data?.celo?.is_epoch_block ? {
//
id: 'epoch_rewards',
//
title: 'Epoch rewards',
//
component: <BlockEpochRewards heightOrHash={ heightOrHash }/>,
//
} : null,
].
filter
(
Boolean
)),
[
blockBlobTxsQuery
,
blockQuery
,
blockTxsQuery
,
blockWithdrawalsQuery
,
hasPagination
,
heightOrHash
]);
let
pagination
;
...
...
@@ -152,7 +152,7 @@ const BlockPageContent = () => {
<>
{ !config.UI.views.block.hiddenFields?.miner && blockQuery.data?.miner && (
<Skeleton
isLoaded={ !
blockQuery.isPlaceholderData }
loading={
blockQuery.isPlaceholderData }
fontFamily="heading"
display="flex"
minW={ 0 }
...
...
@@ -165,7 +165,11 @@ const BlockPageContent = () => {
<AddressEntity address={ blockQuery.data.miner }/>
</Skeleton>
) }
<NetworkExplorers type="block" pathParam={ heightOrHash } ml={{ base: config.UI.views.block.hiddenFields?.miner ? 0 : 3, lg: 'auto' }}/>
<NetworkExplorers
type="block"
pathParam={ heightOrHash }
ml={{ base: config.UI.views.block.hiddenFields?.miner ? 0 : 3, lg: 'auto' }}
/>
</>
);
...
...
@@ -179,10 +183,10 @@ const BlockPageContent = () => {
secondRow={ titleSecondRow }
isLoading={ blockQuery.isPlaceholderData }
/>
{ blockQuery.isPlaceholderData ? <TabsSkeleton tabs={ tabs }/> : (
{ blockQuery.isPlaceholderData ? <
Routed
TabsSkeleton tabs={ tabs }/> : (
<RoutedTabs
tabs={ tabs }
tabL
istProps={ isMobile ? undefined : TAB_LIST_PROPS }
l
istProps={ isMobile ? undefined : TAB_LIST_PROPS }
rightSlot={ hasPagination ? <Pagination { ...(pagination as PaginationParams) }/> : null }
stickyEnabled={ hasPagination }
/>
...
...
ui/shared/DetailsInfoItem.tsx
View file @
730d6ddb
import
{
chakra
,
GridItem
,
Flex
,
Text
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
Skeleton
from
'
ui/shared/chakra/S
keleton
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/s
keleton
'
;
import
*
as
ContainerWithScrollY
from
'
ui/shared/ContainerWithScrollY
'
;
import
Hint
from
'
ui/shared/Hint
'
;
import
HintPopover
from
'
ui/shared/HintPopover
'
;
const
LabelScrollText
=
()
=>
(
<
Text
fontWeight=
{
500
}
variant=
"secondary"
fontSize=
"xs"
className=
"note"
a
lign=
"right"
>
<
Text
fontWeight=
{
500
}
color=
"text.secondary"
fontSize=
"xs"
className=
"note"
textA
lign=
"right"
>
Scroll to see more
</
Text
>
);
...
...
@@ -19,23 +18,20 @@ interface LabelProps {
className
?:
string
;
id
?:
string
;
hasScroll
?:
boolean
;
type
?:
'
tooltip
'
|
'
popover
'
;
}
const
Label
=
chakra
(({
hint
,
children
,
isLoading
,
id
,
className
,
hasScroll
,
type
}:
LabelProps
)
=>
{
const
Label
=
chakra
(({
hint
,
children
,
isLoading
,
id
,
className
,
hasScroll
}:
LabelProps
)
=>
{
return
(
<
GridItem
id=
{
id
}
className=
{
className
}
py=
{
1
}
lineHeight=
{
{
base
:
5
,
lg
:
6
}
}
textStyle=
"md"
_notFirst=
{
{
mt
:
{
base
:
3
,
lg
:
0
}
}
}
>
<
Flex
columnGap=
{
2
}
alignItems=
"flex-start"
>
{
hint
&&
(
type
===
'
popover
'
?
<
HintPopover
label=
{
hint
}
isLoading=
{
isLoading
}
my=
{
{
lg
:
'
2px
'
}
}
/>
:
<
Hint
label=
{
hint
}
isLoading=
{
isLoading
}
my=
{
{
lg
:
'
2px
'
}
}
/>)
}
<
Skeleton
isLoaded=
{
!
isLoading
}
fontWeight=
{
{
base
:
700
,
lg
:
500
}
}
>
{
hint
&&
<
Hint
label=
{
hint
}
isLoading=
{
isLoading
}
my=
{
{
lg
:
'
2px
'
}
}
/>
}
<
Skeleton
loading=
{
isLoading
}
fontWeight=
{
{
base
:
700
,
lg
:
500
}
}
>
{
children
}
{
hasScroll
&&
<
LabelScrollText
/>
}
</
Skeleton
>
...
...
@@ -59,7 +55,7 @@ const Value = chakra(({ children, className }: ValueProps) => {
rowGap=
{
3
}
pl=
{
{
base
:
7
,
lg
:
0
}
}
py=
{
1
}
lineHeight=
{
{
base
:
5
,
lg
:
6
}
}
textStyle=
"md"
whiteSpace=
"nowrap"
>
{
children
}
...
...
ui/shared/DetailsTimestamp.tsx
View file @
730d6ddb
import
React
from
'
react
'
;
import
dayjs
from
'
lib/date/dayjs
'
;
import
Skeleton
from
'
ui/shared/chakra/S
keleton
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/s
keleton
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
TextSeparator
from
'
ui/shared/TextSeparator
'
;
...
...
@@ -15,11 +15,11 @@ const DetailsTimestamp = ({ timestamp, isLoading }: Props) => {
return
(
<>
<
IconSvg
name=
"clock"
boxSize=
{
5
}
color=
"gray.500"
isLoading=
{
isLoading
}
/>
<
Skeleton
isLoaded=
{
!
isLoading
}
ml=
{
2
}
>
<
Skeleton
loading=
{
isLoading
}
ml=
{
2
}
>
{
dayjs
(
timestamp
).
fromNow
()
}
</
Skeleton
>
<
TextSeparator
color=
"gray.500"
/>
<
Skeleton
isLoaded=
{
!
isLoading
}
whiteSpace=
"normal"
>
<
Skeleton
loading=
{
isLoading
}
whiteSpace=
"normal"
>
{
dayjs
(
timestamp
).
format
(
'
llll
'
)
}
</
Skeleton
>
</>
...
...
ui/shared/Hint.tsx
View file @
730d6ddb
...
...
@@ -32,6 +32,7 @@ const Hint = ({ label, className, tooltipProps, isLoading }: Props) => {
<
Tooltip
content=
{
label
}
positioning=
{
{
placement
:
'
top
'
}
}
interactive
{
...
tooltipProps
}
>
<
IconButton
...
...
ui/shared/HintPopover.tsx
deleted
100644 → 0
View file @
34f281d3
import
type
{
PopoverBodyProps
,
PopoverContentProps
,
PopoverProps
}
from
'
@chakra-ui/react
'
;
import
{
DarkMode
,
PopoverArrow
,
PopoverBody
,
PopoverContent
,
PopoverTrigger
,
Portal
,
chakra
,
useColorModeValue
,
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
Popover
from
'
ui/shared/chakra/Popover
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
IconSvg
from
'
./IconSvg
'
;
interface
Props
{
label
:
React
.
ReactNode
;
className
?:
string
;
isLoading
?:
boolean
;
popoverProps
?:
Partial
<
PopoverProps
>
;
popoverContentProps
?:
Partial
<
PopoverContentProps
>
;
popoverBodyProps
?:
Partial
<
PopoverBodyProps
>
;
}
const
HintPopover
=
({
label
,
isLoading
,
className
,
popoverProps
,
popoverContentProps
,
popoverBodyProps
}:
Props
)
=>
{
const
bgColor
=
useColorModeValue
(
'
gray.700
'
,
'
gray.900
'
);
if
(
isLoading
)
{
return
<
Skeleton
className=
{
className
}
boxSize=
{
5
}
borderRadius=
"sm"
/>;
}
return
(
<
Popover
trigger=
"hover"
isLazy
placement=
"top"
{
...
popoverProps
}
>
<
PopoverTrigger
>
<
IconSvg
className=
{
className
}
name=
"info"
boxSize=
{
5
}
color=
"icon_info"
_hover=
{
{
color
:
'
link_hovered
'
}
}
cursor=
"pointer"
/>
</
PopoverTrigger
>
<
Portal
>
<
PopoverContent
bgColor=
{
bgColor
}
maxW=
{
{
base
:
'
calc(100vw - 8px)
'
,
lg
:
'
320px
'
}
}
borderRadius=
"sm"
{
...
popoverContentProps
}
>
<
PopoverArrow
bgColor=
{
bgColor
}
/>
<
PopoverBody
color=
"white"
fontSize=
"sm"
lineHeight=
"20px"
px=
{
2
}
py=
"2px"
{
...
popoverBodyProps
}
>
<
DarkMode
>
{
label
}
</
DarkMode
>
</
PopoverBody
>
</
PopoverContent
>
</
Portal
>
</
Popover
>
);
};
export
default
React
.
memo
(
chakra
(
HintPopover
));
ui/shared/ListItemMobile/ListItemMobileGrid.tsx
View file @
730d6ddb
import
{
Grid
,
chakra
,
GridItem
}
from
'
@chakra-ui/react
'
;
import
{
motion
}
from
'
framer-motion
'
;
import
React
from
'
react
'
;
import
Skeleton
from
'
ui/shared/chakra/S
keleton
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/s
keleton
'
;
interface
ContainerProps
{
className
?:
string
;
isAnimated
?:
boolean
;
animation
?:
string
;
children
:
React
.
ReactNode
;
}
const
Container
=
chakra
(({
isAnimated
,
children
,
className
}:
ContainerProps
)
=>
{
const
Container
=
chakra
(({
animation
,
children
,
className
}:
ContainerProps
)
=>
{
return
(
<
Grid
as=
{
motion
.
div
}
w=
"100%"
initial=
{
isAnimated
?
{
opacity
:
0
,
scale
:
0.97
}
:
{
opacity
:
1
,
scale
:
1
}
}
animate=
{
{
opacity
:
1
,
scale
:
1
}
}
transitionDuration=
"normal"
transitionTimingFunction=
"linear"
animation=
{
animation
}
rowGap=
{
2
}
columnGap=
{
2
}
gridTemplateColumns=
"86px auto"
...
...
@@ -48,7 +43,7 @@ const Label = chakra(({ children, className, isLoading }: LabelProps) => {
return
(
<
Skeleton
className=
{
className
}
isLoaded=
{
!
isLoading
}
loading=
{
isLoading
}
fontWeight=
{
500
}
my=
"5px"
justifySelf=
"start"
...
...
ui/shared/NetworkExplorers.tsx
View file @
730d6ddb
import
{
Image
,
useColorModeValue
,
chakra
,
}
from
'
@chakra-ui/react
'
;
import
{
chakra
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
NetworkExplorer
as
TNetworkExplorer
}
from
'
types/networks
'
;
import
config
from
'
configs/app
'
;
import
stripTrailingSlash
from
'
lib/stripTrailingSlash
'
;
import
{
Image
}
from
'
toolkit/chakra/image
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
LinkExternal
from
'
ui/shared/links/LinkExternal
'
;
import
VerifyWith
from
'
ui/shared/VerifyWith
'
;
interface
Props
{
...
...
@@ -20,24 +17,22 @@ interface Props {
}
const
NetworkExplorers
=
({
className
,
type
,
pathParam
}:
Props
)
=>
{
const
defaultIconColor
=
useColorModeValue
(
'
gray.400
'
,
'
gray.500
'
);
const
explorersLinks
=
React
.
useMemo
(()
=>
{
return
config
.
UI
.
explorers
.
items
.
filter
((
explorer
)
=>
typeof
explorer
.
paths
[
type
]
===
'
string
'
)
.
map
((
explorer
)
=>
{
const
url
=
new
URL
(
stripTrailingSlash
(
explorer
.
paths
[
type
]
||
''
)
+
'
/
'
+
pathParam
,
explorer
.
baseUrl
);
return
(
<
Link
E
xternal
h=
"34px"
key=
{
explorer
.
baseUrl
}
href=
{
url
.
toString
()
}
alignItems=
"center"
display=
"inline-flex"
minW=
"120px"
>
<
Link
e
xternal
h=
"34px"
key=
{
explorer
.
baseUrl
}
href=
{
url
.
toString
()
}
alignItems=
"center"
display=
"inline-flex"
minW=
"120px"
>
{
explorer
.
logo
?
<
Image
boxSize=
{
5
}
mr=
{
2
}
src=
{
explorer
.
logo
}
alt=
{
`${ explorer.title } icon`
}
/>
:
<
IconSvg
name=
"explorer"
boxSize=
{
5
}
color=
{
defaultIconColor
}
mr=
{
2
}
/>
<
IconSvg
name=
"explorer"
boxSize=
{
5
}
color=
{
{
_light
:
'
gray.400
'
,
_dark
:
'
gray.500
'
}
}
mr=
{
2
}
/>
}
{
explorer
.
title
}
</
Link
External
>
</
Link
>
);
});
},
[
pathParam
,
type
,
defaultIconColor
]);
},
[
pathParam
,
type
]);
if
(
explorersLinks
.
length
===
0
)
{
return
null
;
...
...
ui/shared/PopoverTriggerTooltip.tsx
deleted
100644 → 0
View file @
34f281d3
import
{
Tooltip
,
chakra
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
useIsMobile
from
'
lib/hooks/useIsMobile
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
type
Props
=
{
label
:
string
;
isLoading
?:
boolean
;
className
?:
string
;
children
:
React
.
ReactNode
;
};
const
PopoverTriggerTooltip
=
({
label
,
isLoading
,
className
,
children
}:
Props
,
ref
:
React
.
ForwardedRef
<
HTMLDivElement
>
)
=>
{
const
isMobile
=
useIsMobile
();
return
(
// tooltip need to be wrapped in div for proper popover positioning
<
Skeleton
isLoaded=
{
!
isLoading
}
borderRadius=
"base"
ref=
{
ref
}
className=
{
className
}
>
<
Tooltip
label=
{
label
}
isDisabled=
{
isMobile
}
// need a delay to avoid flickering when closing the popover
openDelay=
{
100
}
>
{
children
}
</
Tooltip
>
</
Skeleton
>
);
};
export
default
chakra
(
React
.
forwardRef
(
PopoverTriggerTooltip
));
ui/shared/PrevNext.tsx
View file @
730d6ddb
import
{
Box
,
IconButton
,
chakra
,
Tooltip
,
Flex
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
chakra
,
Flex
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
{
IconButton
}
from
'
toolkit/chakra/icon-button
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
{
Tooltip
}
from
'
toolkit/chakra/tooltip
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
interface
Props
{
...
...
@@ -26,38 +28,44 @@ const PrevNext = ({ className, onClick, prevLabel, nextLabel, isPrevDisabled, is
if
(
isLoading
)
{
return
(
<
Flex
columnGap=
"10px"
className=
{
className
}
>
<
Skeleton
boxSize=
{
6
}
borderRadius=
"sm"
/>
<
Skeleton
boxSize=
{
6
}
borderRadius=
"sm"
/>
<
Skeleton
loading
boxSize=
{
6
}
borderRadius=
"sm"
/>
<
Skeleton
loading
boxSize=
{
6
}
borderRadius=
"sm"
/>
</
Flex
>
);
}
return
(
<
Box
className=
{
className
}
display=
"flex"
>
<
Tooltip
label
=
{
prevLabel
}
>
<
Tooltip
content
=
{
prevLabel
}
>
<
IconButton
aria
-
label=
"prev"
icon=
{
<
IconSvg
name=
"arrows/east-mini"
boxSize=
{
6
}
/>
}
h=
{
6
}
borderRadius=
"sm"
variant=
"subtle"
colorScheme=
"gray"
bg=
"gray.100"
color=
"gray.600"
_hover=
{
{
color
:
'
link.primary.hover
'
,
}
}
onClick=
{
handelPrevClick
}
isDisabled=
{
isPrevDisabled
}
/>
disabled=
{
isPrevDisabled
}
>
<
IconSvg
name=
"arrows/east-mini"
boxSize=
{
6
}
/>
</
IconButton
>
</
Tooltip
>
<
Tooltip
label
=
{
nextLabel
}
>
<
Tooltip
content
=
{
nextLabel
}
>
<
IconButton
aria
-
label=
"next"
icon=
{
<
IconSvg
name=
"arrows/east-mini"
boxSize=
{
6
}
transform=
"rotate(180deg)"
/>
}
h=
{
6
}
borderRadius=
"sm"
variant=
"subtle"
colorScheme=
"gray"
bg=
"gray.100"
color=
"gray.600"
_hover=
{
{
color
:
'
link.primary.hover
'
,
}
}
ml=
"10px"
onClick=
{
handelNextClick
}
isDisabled=
{
isNextDisabled
}
/>
disabled=
{
isNextDisabled
}
>
<
IconSvg
name=
"arrows/east-mini"
boxSize=
{
6
}
transform=
"rotate(180deg)"
/>
</
IconButton
>
</
Tooltip
>
</
Box
>
);
...
...
ui/shared/RawDataSnippet.tsx
View file @
730d6ddb
import
type
{
ChakraProps
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
Flex
,
chakra
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
type
{
HTML
ChakraProps
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
Flex
,
chakra
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
Skeleton
from
'
ui/shared/chakra/S
keleton
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/s
keleton
'
;
import
CopyToClipboard
from
'
./CopyToClipboard
'
;
...
...
@@ -16,7 +16,7 @@ interface Props {
textareaMinHeight
?:
string
;
showCopy
?:
boolean
;
isLoading
?:
boolean
;
contentProps
?:
ChakraProps
;
contentProps
?:
HTMLChakraProps
<
'
div
'
>
;
}
const
RawDataSnippet
=
({
...
...
@@ -36,12 +36,12 @@ const RawDataSnippet = ({
// so blackAlpha.50 here is replaced with #f5f5f6
// and whiteAlpha.50 is replaced with #1a1b1b
// const bgColor = useColorModeValue('blackAlpha.50', 'whiteAlpha.50');
const
bgColor
=
useColorModeValue
(
'
#f5f5f6
'
,
'
#1a1b1b
'
)
;
const
bgColor
=
{
_light
:
'
#f5f5f6
'
,
_dark
:
'
#1a1b1b
'
}
;
return
(
<
Box
className=
{
className
}
as=
"section"
title=
{
title
}
>
{
(
title
||
rightSlot
||
showCopy
)
&&
(
<
Flex
justifyContent=
{
title
?
'
space-between
'
:
'
flex-end
'
}
alignItems=
"center"
mb=
{
3
}
>
{
title
&&
<
Skeleton
fontWeight=
{
500
}
isLoaded=
{
!
isLoading
}
>
{
title
}
</
Skeleton
>
}
{
title
&&
<
Skeleton
fontWeight=
{
500
}
loading=
{
isLoading
}
>
{
title
}
</
Skeleton
>
}
{
rightSlot
}
{
typeof
data
===
'
string
'
&&
showCopy
&&
<
CopyToClipboard
text=
{
data
}
isLoading=
{
isLoading
}
/>
}
</
Flex
>
...
...
@@ -58,7 +58,7 @@ const RawDataSnippet = ({
whiteSpace=
"pre-wrap"
overflowX=
"hidden"
overflowY=
"auto"
isLoaded=
{
!
isLoading
}
loading=
{
isLoading
}
{
...
contentProps
}
>
{
data
}
...
...
ui/shared/VerifyWith.tsx
View file @
730d6ddb
import
{
Button
,
PopoverTrigger
,
PopoverBody
,
PopoverContent
,
Show
,
Hide
,
chakra
,
useDisclosure
,
Grid
,
}
from
'
@chakra-ui/react
'
;
import
{
Box
,
chakra
,
Grid
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
Popover
from
'
ui/shared/chakra/Popover
'
;
import
{
Button
}
from
'
toolkit/chakra/button
'
;
import
{
PopoverBody
,
PopoverContent
,
PopoverRoot
,
PopoverTrigger
}
from
'
toolkit/chakra/popover
'
;
import
{
Tooltip
}
from
'
toolkit/chakra/tooltip
'
;
import
{
useDisclosure
}
from
'
toolkit/hooks/useDisclosure
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
import
PopoverTriggerTooltip
from
'
ui/shared/PopoverTriggerTooltip
'
;
interface
Props
{
className
?:
string
;
...
...
@@ -24,39 +16,34 @@ interface Props {
}
const
VerifyWith
=
({
className
,
links
,
label
,
longText
,
shortText
}:
Props
)
=>
{
const
{
isOpen
,
onToggle
,
onClose
}
=
useDisclosure
();
const
{
open
,
onOpenChange
}
=
useDisclosure
();
return
(
<
Popover
isOpen=
{
isOpen
}
onClose=
{
onClose
}
placement=
"bottom-start"
isLazy
>
<
Popover
Root
positioning=
{
{
placement
:
'
bottom-start
'
}
}
open=
{
open
}
onOpenChange=
{
onOpenChange
}
>
<
PopoverTrigger
>
<
PopoverTriggerTooltip
label=
{
label
}
className=
{
className
}
>
<
Button
size=
"sm"
variant=
"outline"
colorScheme=
"gray"
onClick=
{
onToggle
}
isActive=
{
isOpen
}
aria
-
label=
{
label
}
fontWeight=
{
500
}
px=
{
shortText
?
2
:
1
}
h=
"32px"
flexShrink=
{
0
}
>
<
IconSvg
name=
"explorer"
boxSize=
{
5
}
/>
<
Show
above=
"xl"
>
<
chakra
.
span
ml=
{
1
}
>
{
longText
}
</
chakra
.
span
>
</
Show
>
{
shortText
&&
(
<
Hide
above=
"xl"
>
<
chakra
.
span
ml=
{
1
}
>
{
shortText
}
</
chakra
.
span
>
</
Hide
>
)
}
</
Button
>
</
PopoverTriggerTooltip
>
<
Box
className=
{
className
}
>
<
Tooltip
content=
{
label
}
disableOnMobile
disabled=
{
open
}
>
<
Button
size=
"sm"
variant=
"dropdown"
expanded=
{
open
}
aria
-
label=
{
label
}
fontWeight=
{
500
}
px=
{
shortText
?
2
:
1
}
flexShrink=
{
0
}
columnGap=
{
1
}
>
<
IconSvg
name=
"explorer"
boxSize=
{
5
}
/>
<
chakra
.
span
hideBelow=
"xl"
>
{
longText
}
</
chakra
.
span
>
{
shortText
&&
<
chakra
.
span
hideFrom=
"xl"
>
{
shortText
}
</
chakra
.
span
>
}
</
Button
>
</
Tooltip
>
</
Box
>
</
PopoverTrigger
>
<
PopoverContent
w=
"auto"
>
<
PopoverBody
>
<
chakra
.
span
color=
"text
_secondary"
fontSiz
e=
"xs"
>
{
label
}
</
chakra
.
span
>
<
chakra
.
span
color=
"text
.secondary"
textStyl
e=
"xs"
>
{
label
}
</
chakra
.
span
>
<
Grid
alignItems=
"center"
templateColumns=
{
links
.
length
>
1
?
'
auto auto
'
:
'
1fr
'
}
...
...
@@ -68,7 +55,7 @@ const VerifyWith = ({ className, links, label, longText, shortText }: Props) =>
</
Grid
>
</
PopoverBody
>
</
PopoverContent
>
</
Popover
>
</
Popover
Root
>
);
};
...
...
ui/shared/alerts/ServiceDegradationWarning.tsx
View file @
730d6ddb
import
{
Alert
,
Spinner
,
chakra
}
from
'
@chakra-ui/react
'
;
import
{
Spinner
,
chakra
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
{
Alert
}
from
'
toolkit/chakra/alert
'
;
interface
Props
{
isLoading
?:
boolean
;
...
...
@@ -10,12 +10,14 @@ interface Props {
const
ServiceDegradationWarning
=
({
isLoading
,
className
}:
Props
)
=>
{
return
(
<
Skeleton
className=
{
className
}
isLoaded=
{
!
isLoading
}
>
<
Alert
status=
"warning"
colorScheme=
"gray"
alignItems=
{
{
base
:
'
flex-start
'
,
lg
:
'
center
'
}
}
>
<
Spinner
size=
"sm"
mr=
{
2
}
my=
{
{
base
:
'
3px
'
,
lg
:
0
}
}
flexShrink=
{
0
}
/>
Data sync in progress... page will refresh automatically once data is available
</
Alert
>
</
Skeleton
>
<
Alert
loading=
{
isLoading
}
status=
"neutral"
className=
{
className
}
startElement=
{
<
Spinner
size=
"sm"
my=
"3px"
flexShrink=
{
0
}
/>
}
>
Data sync in progress... page will refresh automatically once data is available
</
Alert
>
);
};
...
...
ui/shared/batch/OptimisticL2TxnBatchDA.tsx
View file @
730d6ddb
...
...
@@ -3,7 +3,7 @@ import React from 'react';
import
type
{
OptimisticL2TxnBatchesItem
}
from
'
types/api/optimisticL2
'
;
import
type
{
ExcludeUndefined
}
from
'
types/utils
'
;
import
Tag
from
'
ui/shared/chakra/Tag
'
;
import
{
Badge
}
from
'
toolkit/chakra/badge
'
;
export
interface
Props
{
container
:
ExcludeUndefined
<
OptimisticL2TxnBatchesItem
[
'
batch_data_container
'
]
>
;
...
...
@@ -24,9 +24,9 @@ const OptimisticL2TxnBatchDA = ({ container, isLoading }: Props) => {
})();
return
(
<
Tag
colorScheme=
"yellow"
isL
oading=
{
isLoading
}
>
<
Badge
colorScheme=
"yellow"
l
oading=
{
isLoading
}
>
{
text
}
</
Tag
>
</
Badge
>
);
};
...
...
ui/shared/verificationSteps/VerificationSteps.tsx
View file @
730d6ddb
...
...
@@ -3,7 +3,7 @@ import React from 'react';
import
type
{
Step
}
from
'
./types
'
;
import
Skeleton
from
'
ui/shared/chakra/S
keleton
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/s
keleton
'
;
import
VerificationStep
from
'
./VerificationStep
'
;
...
...
@@ -25,7 +25,7 @@ const VerificationSteps = ({ currentStep, currentStepPending, steps, isLoading,
return
(
<
Skeleton
className=
{
className
}
isLoaded=
{
!
isLoading
}
loading=
{
isLoading
}
display=
"flex"
gap=
{
2
}
alignItems=
"center"
...
...
ui/showcases/Alerts.tsx
View file @
730d6ddb
import
{
Box
,
Table
}
from
'
@chakra-ui/react
'
;
import
{
Box
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
{
Alert
}
from
'
toolkit/chakra/alert
'
;
import
{
TableBody
,
TableColumnHeader
,
TableHeader
,
TableRoot
,
TableRow
}
from
'
toolkit/chakra/table
'
;
import
*
as
SocketNewItemsNotice
from
'
ui/shared/SocketNewItemsNotice
'
;
import
{
Section
,
Container
,
SectionHeader
,
SamplesStack
,
Sample
,
SectionSubHeader
}
from
'
./parts
'
;
...
...
@@ -12,20 +13,20 @@ const AlertsShowcase = () => {
<
Section
>
<
SectionHeader
>
Status
</
SectionHeader
>
<
SamplesStack
>
<
Sample
label=
"
visual
: info"
>
<
Alert
visual
=
"info"
title=
"Info"
>
Alert content
</
Alert
>
<
Sample
label=
"
status
: info"
>
<
Alert
status
=
"info"
title=
"Info"
>
Alert content
</
Alert
>
</
Sample
>
<
Sample
label=
"
visual
: neutral"
>
<
Alert
visual
=
"neutral"
title=
"Neutral"
>
Alert content
</
Alert
>
<
Sample
label=
"
status
: neutral"
>
<
Alert
status
=
"neutral"
title=
"Neutral"
>
Alert content
</
Alert
>
</
Sample
>
<
Sample
label=
"
visual
: warning"
>
<
Alert
visual
=
"warning"
title=
"Warning"
>
Alert content
</
Alert
>
<
Sample
label=
"
status
: warning"
>
<
Alert
status
=
"warning"
title=
"Warning"
>
Alert content
</
Alert
>
</
Sample
>
<
Sample
label=
"
visual
: success"
>
<
Alert
visual
=
"success"
title=
"Success"
>
Alert content
</
Alert
>
<
Sample
label=
"
status
: success"
>
<
Alert
status
=
"success"
title=
"Success"
>
Alert content
</
Alert
>
</
Sample
>
<
Sample
label=
"
visual
: error"
>
<
Alert
visual
=
"error"
title=
"Error"
>
Alert content
</
Alert
>
<
Sample
label=
"
status
: error"
>
<
Alert
status
=
"error"
title=
"Error"
>
Alert content
</
Alert
>
</
Sample
>
</
SamplesStack
>
</
Section
>
...
...
@@ -33,7 +34,7 @@ const AlertsShowcase = () => {
<
SectionHeader
>
Variant
</
SectionHeader
>
<
SamplesStack
>
<
Sample
label=
"variant: subtle"
>
<
Alert
visual
=
"info"
title=
"Info"
>
Alert content
</
Alert
>
<
Alert
status
=
"info"
title=
"Info"
>
Alert content
</
Alert
>
</
Sample
>
</
SamplesStack
>
</
Section
>
...
...
@@ -42,56 +43,56 @@ const AlertsShowcase = () => {
<
SectionSubHeader
>
Inside table (SocketNewItemsNotice)
</
SectionSubHeader
>
<
SamplesStack
>
<
Sample
label=
"loading"
>
<
Table
.
Root
>
<
Table
.
Header
>
<
Table
.
Row
>
<
Table
.
ColumnHeader
w=
"100px"
>
Block
</
Table
.
ColumnHeader
>
<
Table
.
ColumnHeader
w=
"100px"
>
Age
</
Table
.
ColumnHeader
>
<
Table
.
ColumnHeader
w=
"100px"
>
Gas used
</
Table
.
ColumnHeader
>
</
Table
.
Row
>
</
Table
.
Header
>
<
Table
.
Body
>
<
Table
Root
tableLayout=
"auto"
>
<
TableHeader
>
<
TableRow
>
<
Table
ColumnHeader
w=
"100px"
>
Block
</
Table
ColumnHeader
>
<
Table
ColumnHeader
w=
"100px"
>
Age
</
Table
ColumnHeader
>
<
Table
ColumnHeader
w=
"100px"
>
Gas used
</
Table
ColumnHeader
>
</
TableRow
>
</
TableHeader
>
<
TableBody
>
<
SocketNewItemsNotice
.
Desktop
url=
{
window
.
location
.
href
}
num=
{
1234
}
type=
"block"
isLoading
/>
</
Table
.
Body
>
</
Table
.
Root
>
</
TableBody
>
</
TableRoot
>
</
Sample
>
<
Sample
label=
"success"
>
<
Table
.
Root
>
<
Table
.
Header
>
<
Table
.
Row
>
<
Table
.
ColumnHeader
w=
"100px"
>
Block
</
Table
.
ColumnHeader
>
<
Table
.
ColumnHeader
w=
"100px"
>
Age
</
Table
.
ColumnHeader
>
<
Table
.
ColumnHeader
w=
"100px"
>
Gas used
</
Table
.
ColumnHeader
>
</
Table
.
Row
>
</
Table
.
Header
>
<
Table
.
Body
>
<
Table
Root
tableLayout=
"auto"
>
<
TableHeader
>
<
TableRow
>
<
Table
ColumnHeader
w=
"100px"
>
Block
</
Table
ColumnHeader
>
<
Table
ColumnHeader
w=
"100px"
>
Age
</
Table
ColumnHeader
>
<
Table
ColumnHeader
w=
"100px"
>
Gas used
</
Table
ColumnHeader
>
</
TableRow
>
</
TableHeader
>
<
TableBody
>
<
SocketNewItemsNotice
.
Desktop
url=
{
window
.
location
.
href
}
num=
{
1234
}
type=
"block"
isLoading=
{
false
}
/>
</
Table
.
Body
>
</
Table
.
Root
>
</
TableBody
>
</
TableRoot
>
</
Sample
>
</
SamplesStack
>
<
SectionSubHeader
>
Multiple lines
</
SectionSubHeader
>
<
SamplesStack
>
<
Sample
label=
"multiple lines, with title, inline=false"
>
<
Alert
visual
=
"warning"
title=
"Warning"
inline=
{
false
}
maxWidth=
"500px"
>
<
Alert
status
=
"warning"
title=
"Warning"
inline=
{
false
}
maxWidth=
"500px"
>
<
Box
>
Participated in our recent Blockscout activities? Check your eligibility and claim your NFT Scout badges. More exciting things are coming soon!
</
Box
>
</
Alert
>
</
Sample
>
<
Sample
label=
"multiple lines, no title"
>
<
Alert
visual
=
"warning"
maxWidth=
"500px"
>
<
Alert
status
=
"warning"
maxWidth=
"500px"
>
<
Box
>
Participated in our recent Blockscout activities? Check your eligibility and claim your NFT Scout badges. More exciting things are coming soon!
</
Box
>
...
...
ui/showcases/Links.tsx
View file @
730d6ddb
...
...
@@ -102,7 +102,7 @@ const LinksShowcase = () => {
</
CutLink
>
</
Sample
>
<
Sample
label=
"Loading"
flexDirection=
"column"
alignItems=
"flex-start"
>
<
CutLink
id=
"CutLink_2"
isL
oading
>
<
CutLink
id=
"CutLink_2"
l
oading
>
<
Box
maxW=
"500px"
>
{
TEXT
}
</
Box
>
</
CutLink
>
</
Sample
>
...
...
ui/txnBatches/zkSyncL2/ZkSyncL2TxnBatchHashesInfo.tsx
View file @
730d6ddb
...
...
@@ -3,7 +3,7 @@ import React from 'react';
import
type
{
ZkSyncBatch
}
from
'
types/api/zkSyncL2
'
;
import
Skeleton
from
'
ui/shared/chakra/S
keleton
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/s
keleton
'
;
import
*
as
DetailsInfoItem
from
'
ui/shared/DetailsInfoItem
'
;
import
DetailsTimestamp
from
'
ui/shared/DetailsTimestamp
'
;
import
TxEntityL1
from
'
ui/shared/entities/tx/TxEntityL1
'
;
...
...
@@ -48,7 +48,7 @@ const ZkSyncL2TxnBatchHashesInfo = ({ isLoading, data }: Props) => {
</
Flex
>
)
}
</>
)
:
<
Skeleton
isLoaded=
{
!
isLoading
}
>
Pending
</
Skeleton
>
}
)
:
<
Skeleton
loading=
{
isLoading
}
>
Pending
</
Skeleton
>
}
</
DetailsInfoItem
.
Value
>
<
DetailsInfoItem
.
Label
...
...
@@ -75,7 +75,7 @@ const ZkSyncL2TxnBatchHashesInfo = ({ isLoading, data }: Props) => {
</
Flex
>
)
}
</>
)
:
<
Skeleton
isLoaded=
{
!
isLoading
}
>
Pending
</
Skeleton
>
}
)
:
<
Skeleton
loading=
{
isLoading
}
>
Pending
</
Skeleton
>
}
</
DetailsInfoItem
.
Value
>
<
DetailsInfoItem
.
Label
...
...
@@ -102,7 +102,7 @@ const ZkSyncL2TxnBatchHashesInfo = ({ isLoading, data }: Props) => {
</
Flex
>
)
}
</>
)
:
<
Skeleton
isLoaded=
{
!
isLoading
}
>
Pending
</
Skeleton
>
}
)
:
<
Skeleton
loading=
{
isLoading
}
>
Pending
</
Skeleton
>
}
</
DetailsInfoItem
.
Value
>
</>
);
...
...
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