Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 1 addition & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const RESTRICTED_MODULES = {
'Heading', 'Badge', 'Tabs', 'Show', 'Hide', 'Checkbox', 'CheckboxGroup',
'Table', 'TableRoot', 'TableBody', 'TableHeader', 'TableRow', 'TableCell',
'Menu', 'MenuRoot', 'MenuTrigger', 'MenuContent', 'MenuItem', 'MenuTriggerItem', 'MenuRadioItemGroup', 'MenuContextTrigger',
'Rating', 'RatingGroup', 'Textarea',
'Rating', 'RatingGroup', 'Textarea', 'Progress', 'ProgressCircle',
],
message: 'Please use corresponding component or hook from "toolkit" instead',
},
Expand Down
19 changes: 19 additions & 0 deletions toolkit/chakra/progress.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Progress as ChakraProgress } from '@chakra-ui/react';
import * as React from 'react';

interface ProgressProps extends ChakraProgress.RootProps {
trackProps?: ChakraProgress.TrackProps;
}

export const Progress = React.forwardRef<HTMLDivElement, ProgressProps>(
function Progress(props, ref) {
const { trackProps, color, ...rest } = props;
return (
<ChakraProgress.Root { ...rest } ref={ ref }>
<ChakraProgress.Track { ...trackProps }>
<ChakraProgress.Range bg={ color }/>
</ChakraProgress.Track>
</ChakraProgress.Root>
);
},
);
7 changes: 6 additions & 1 deletion toolkit/theme/foundations/semanticTokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,13 @@ const semanticTokens: ThemingConfig['semanticTokens'] = {
shadow: { value: { _light: '{colors.blackAlpha.200}', _dark: '{colors.whiteAlpha.300}' } },
},
},
progress: {
track: {
DEFAULT: { value: { _light: '{colors.gray.100}', _dark: '{colors.whiteAlpha.100}' } },
},
},
progressCircle: {
trackColor: {
track: {
DEFAULT: { value: { _light: '{colors.gray.100}', _dark: '{colors.whiteAlpha.100}' } },
},
},
Expand Down
2 changes: 2 additions & 0 deletions toolkit/theme/recipes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { recipe as menu } from './menu.recipe';
import { recipe as pinInput } from './pin-input.recipe';
import { recipe as popover } from './popover.recipe';
import { recipe as progressCircle } from './progress-circle.recipe';
import { recipe as progress } from './progress.recipe';
import { recipe as radioGroup } from './radio-group.recipe';
import { recipe as radiomark } from './radiomark.recipe';
import { recipe as ratingGroup } from './rating-group.recipe';
Expand Down Expand Up @@ -54,6 +55,7 @@ export const slotRecipes = {
menu,
pinInput,
popover,
progress,
progressCircle,
radioGroup,
ratingGroup,
Expand Down
2 changes: 1 addition & 1 deletion toolkit/theme/recipes/progress-circle.recipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const recipe = defineSlotRecipe({
},
},
circleTrack: {
'--track-color': 'colors.progressCircle.trackColor',
'--track-color': 'colors.progressCircle.track',
stroke: 'var(--track-color)',
},
circleRange: {
Expand Down
115 changes: 115 additions & 0 deletions toolkit/theme/recipes/progress.recipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { defineSlotRecipe } from '@chakra-ui/react';

export const recipe = defineSlotRecipe({
slots: [ 'root', 'track', 'range', 'label', 'valueText' ],
className: 'chakra-progress',
base: {
root: {
textStyle: 'sm',
position: 'relative',
},
track: {
overflow: 'hidden',
position: 'relative',
borderRadius: 'base',
},
range: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
transitionProperty: 'width, height',
transitionDuration: 'slow',
height: '100%',
bgColor: 'var(--track-color)',
_indeterminate: {
'--animate-from-x': '-40%',
'--animate-to-x': '100%',
position: 'absolute',
willChange: 'left',
minWidth: '50%',
animation: 'position 1s ease infinite normal none running',
backgroundImage: `linear-gradient(to right, transparent 0%, var(--track-color) 50%, transparent 100%)`,
},
},
label: {
display: 'inline-flex',
fontWeight: 'medium',
alignItems: 'center',
gap: '1',
},
valueText: {
textStyle: 'xs',
lineHeight: '1',
fontWeight: 'medium',
},
},

variants: {
variant: {
subtle: {
track: {
bgColor: 'progress.track',
},
range: {
bgColor: 'selected.option.bg',
},
},
},

shape: {
rounded: {
track: {
borderRadius: 'base',
},
},
},

striped: {
'true': {
range: {
// eslint-disable-next-line max-len
backgroundImage: `linear-gradient(45deg, var(--stripe-color) 25%, transparent 25%, transparent 50%, var(--stripe-color) 50%, var(--stripe-color) 75%, transparent 75%, transparent)`,
backgroundSize: `var(--stripe-size) var(--stripe-size)`,
'--stripe-size': '1rem',
'--stripe-color': {
_light: 'rgba(255, 255, 255, 0.3)',
_dark: 'rgba(0, 0, 0, 0.3)',
},
},
},
},

animated: {
'true': {
range: {
'--animate-from': 'var(--stripe-size)',
animation: 'bg-position 1s linear infinite',
},
},
},

size: {
xs: {
track: { h: '1' },
},
sm: {
track: { h: '2' },
},
md: {
track: { h: '3' },
},
lg: {
track: { h: '4' },
},
xl: {
track: { h: '8' },
},
},
},

defaultVariants: {
variant: 'subtle',
size: 'xs',
shape: 'rounded',
},
});
2 changes: 2 additions & 0 deletions ui/pages/Chakra.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import MenuShowcase from 'ui/showcases/Menu';
import PaginationShowcase from 'ui/showcases/Pagination';
import PinInputShowcase from 'ui/showcases/PinInput';
import PopoverShowcase from 'ui/showcases/Popover';
import ProgressShowcase from 'ui/showcases/Progress';
import ProgressCircleShowcase from 'ui/showcases/ProgressCircle';
import RadioShowcase from 'ui/showcases/Radio';
import RatingShowcase from 'ui/showcases/Rating';
Expand Down Expand Up @@ -54,6 +55,7 @@ const tabs = [
{ label: 'Link', value: 'link', component: <LinkShowcase/> },
{ label: 'Menu', value: 'menu', component: <MenuShowcase/> },
{ label: 'Pagination', value: 'pagination', component: <PaginationShowcase/> },
{ label: 'Progress', value: 'progress', component: <ProgressShowcase/> },
{ label: 'Progress Circle', value: 'progress-circle', component: <ProgressCircleShowcase/> },
{ label: 'Radio', value: 'radio', component: <RadioShowcase/> },
{ label: 'Rating', value: 'rating', component: <RatingShowcase/> },
Expand Down
15 changes: 9 additions & 6 deletions ui/rewards/dashboard/streakModal/BadgeCard.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { Flex, Text, Progress } from '@chakra-ui/react';
import { Flex, Text } from '@chakra-ui/react';

import type { GetAvailableBadgesResponse } from '@blockscout/points-types';

import { Image } from 'toolkit/chakra/image';
import { Link } from 'toolkit/chakra/link';
import { Progress } from 'toolkit/chakra/progress';

const BADGE_BG_COLORS = [ '#DFE8F5', '#D2E5FE', '#EFE1FF' ];

Expand Down Expand Up @@ -81,11 +82,13 @@ export default function BadgeCard({ badge, currentStreak, index }: Props) {
<Text textStyle="xs" color="text.secondary" minW="50px">
{ progress }/{ target }
</Text>
<Progress.Root value={ progress } min={ 0 } max={ target } flex={ 1 } size="xs" variant="subtle">
<Progress.Track h="4px" bg={{ _light: 'gray.200', _dark: 'whiteAlpha.200' }}>
<Progress.Range bg="green.400"/>
</Progress.Track>
</Progress.Root>
<Progress
value={ progress }
min={ 0 }
max={ target }
flex={ 1 }
color="green.400"
/>
</>
);
})() }
Expand Down
25 changes: 10 additions & 15 deletions ui/rewards/dashboard/streakModal/ProgressSegment.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Flex, Text, Progress } from '@chakra-ui/react';
import { Flex, Text } from '@chakra-ui/react';
import { clamp } from 'es-toolkit';

import { Progress } from 'toolkit/chakra/progress';
import IconSvg from 'ui/shared/IconSvg';

type Props = {
Expand All @@ -17,23 +18,17 @@ export default function ProgressSegment({ value, target, prevTarget, isFirst }:
return (
<Flex gap={ 0 } flex={{ base: isFirst ? 0.7 : 1, lg: 1 }} minW="0">
<Flex flex={ 1 } alignItems="center" h={{ base: '32px', lg: '40px' }} mx={ -2.5 }>
<Progress.Root
<Progress
value={ progress }
min={ prevTarget }
max={ target }
size="xs"
variant="subtle"
w="full"
>
<Progress.Track
h="4px"
bg={{ _light: 'gray.200', _dark: 'whiteAlpha.200' }}
borderStartRadius={ isFirst ? undefined : 0 }
borderEndRadius={ 0 }
>
<Progress.Range bg="green.400"/>
</Progress.Track>
</Progress.Root>
color="green.400"
trackProps={{
borderStartRadius: isFirst ? undefined : 0,
borderEndRadius: 0,
}}
/>
</Flex>
<Flex
direction="column"
Expand All @@ -47,7 +42,7 @@ export default function ProgressSegment({ value, target, prevTarget, isFirst }:
w="40px"
h="32px"
borderRadius="lg"
bgColor={ isDone ? 'green.400' : { _light: 'gray.200', _dark: 'whiteAlpha.200' } }
bgColor={ isDone ? 'green.400' : 'progress.track' }
alignItems="center"
justifyContent="center"
zIndex={ 1 }
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 31 additions & 0 deletions ui/showcases/Progress.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';

import { Progress } from 'toolkit/chakra/progress';

import { Section, Container, SectionHeader, SamplesStack, Sample } from './parts';

const ProgressShowcase = () => {

return (
<Container value="progress">
<Section>
<SectionHeader>Size</SectionHeader>
<SamplesStack >
{ ([ 'sm', 'md', 'lg', 'xl' ] as const).map((size) => (
<Sample key={ size } label={ `size: ${ size }` }>
<Progress
w="200px"
min={ 0 }
max={ 100 }
value={ 45 }
size={ size }
/>
</Sample>
)) }
</SamplesStack>
</Section>
</Container>
);
};

export default React.memo(ProgressShowcase);
Loading