-
Notifications
You must be signed in to change notification settings - Fork 0
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
Feature/progress indicator #43
base: main
Are you sure you want to change the base?
Changes from all commits
61932fa
2970553
b7d3054
7aef427
cbead83
eecf98d
294ac02
74ab4c7
a4830d6
21287b9
0a8967f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import type { ComponentMeta, ComponentStory } from '@storybook/react'; | ||
|
||
import { CircularExample, LinearExample } from './ProgressIndicator'; | ||
|
||
export default { | ||
title: 'components/ProgressIndicator', | ||
component: LinearExample, | ||
} as ComponentMeta<typeof LinearExample>; | ||
|
||
export const Linear: ComponentStory<typeof LinearExample> = args => <LinearExample {...args} />; | ||
|
||
Linear.args = { | ||
progress: 0.45, | ||
indeterminateDuration: 2000, | ||
// to counteract align center by the parent | ||
containerStyle: { | ||
alignSelf: 'stretch', | ||
}, | ||
}; | ||
|
||
Linear.parameters = { | ||
docs: { | ||
source: { | ||
code: ` | ||
<ProgressIndicator.Linear progress={0.45} animating {...rest} /> | ||
`, | ||
language: 'tsx', | ||
type: 'auto', | ||
}, | ||
}, | ||
}; | ||
|
||
export const Circular: ComponentStory<typeof CircularExample> = args => ( | ||
<CircularExample {...args} /> | ||
); | ||
|
||
Circular.args = { | ||
progress: 0.45, | ||
}; | ||
|
||
Circular.parameters = { | ||
docs: { | ||
source: { | ||
code: ` | ||
<ProgressIndicator.Linear color="colors.primary" size={30} animating {...rest} /> | ||
`, | ||
language: 'tsx', | ||
type: 'auto', | ||
}, | ||
}, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { | ||
useMolecules, | ||
CircularProgressIndicatorProps, | ||
LinearProgressIndicatorProps, | ||
} from 'bamboo-molecules'; | ||
|
||
export const CircularExample = (props: CircularProgressIndicatorProps) => { | ||
const { ProgressIndicator } = useMolecules(); | ||
|
||
return <ProgressIndicator.Circular {...props} />; | ||
}; | ||
|
||
export const LinearExample = (props: LinearProgressIndicatorProps) => { | ||
const { ProgressIndicator } = useMolecules(); | ||
|
||
return <ProgressIndicator.Linear {...props} />; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,29 +16,20 @@ const AnimatedSpinner = ({ | |
color: string; | ||
styles: StyleProp<any>; | ||
}) => { | ||
const containerStyle = useMemo( | ||
() => ({ | ||
width: size, | ||
height: size / 2, | ||
overflow: 'hidden' as const, | ||
}), | ||
[size], | ||
); | ||
const offsetContainerStyles = useMemo(() => { | ||
const offsetStyle = index ? { top: size / 2 } : null; | ||
|
||
return [containerStyle, offsetStyle]; | ||
}, [containerStyle, index, size]); | ||
|
||
const frames = (60 * duration) / 1000; | ||
const easing = Easing.bezier(0.4, 0.0, 0.7, 1.0); | ||
const inputRange = useMemo( | ||
() => Array.from(new Array(frames), (_, frameIndex) => frameIndex / (frames - 1)), | ||
[frames], | ||
); | ||
const outputRange = useMemo( | ||
() => | ||
Array.from(new Array(frames), (_, frameIndex) => { | ||
const { containerStyle, offsetContainerStyle, layerStyle, viewportStyle, lineStyle } = | ||
useMemo(() => { | ||
const _containerStyle = { | ||
width: size, | ||
height: size / 2, | ||
overflow: 'hidden' as const, | ||
}; | ||
const frames = (60 * duration) / 1000; | ||
const easing = Easing.bezier(0.4, 0.0, 0.7, 1.0); | ||
const inputRange = Array.from( | ||
new Array(frames), | ||
(_, frameIndex) => frameIndex / (frames - 1), | ||
); | ||
const outputRange = Array.from(new Array(frames), (_, frameIndex) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. needs to be broken down into a separate function and be memoized. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same for input range |
||
let progress = (2 * frameIndex) / (frames - 1); | ||
const rotation = index ? +(360 - 15) : -(180 - 15); | ||
|
||
|
@@ -49,48 +40,49 @@ const AnimatedSpinner = ({ | |
const direction = index ? -1 : +1; | ||
|
||
return `${direction * (180 - 30) * easing(progress) + rotation}deg`; | ||
}), | ||
[easing, frames, index], | ||
); | ||
|
||
const layerStyle = { | ||
width: size, | ||
height: size, | ||
transform: [ | ||
{ | ||
rotate: timer.interpolate({ | ||
inputRange: [0, 1], | ||
outputRange: [`${0 + 30 + 15}deg`, `${2 * 360 + 30 + 15}deg`], | ||
}), | ||
}, | ||
], | ||
}; | ||
|
||
const viewportStyle = { | ||
width: size, | ||
height: size, | ||
transform: [ | ||
{ | ||
translateY: index ? -size / 2 : 0, | ||
}, | ||
{ | ||
rotate: timer.interpolate({ inputRange, outputRange }), | ||
}, | ||
], | ||
}; | ||
}); | ||
|
||
const lineStyle = { | ||
width: size, | ||
height: size, | ||
borderColor: color, | ||
borderWidth: size / 10, | ||
borderRadius: size / 2, | ||
}; | ||
return { | ||
containerStyle: _containerStyle, | ||
offsetContainerStyle: [_containerStyle, index ? { top: size / 2 } : null], | ||
layerStyle: { | ||
width: size, | ||
height: size, | ||
transform: [ | ||
{ | ||
rotate: timer.interpolate({ | ||
inputRange: [0, 1], | ||
outputRange: [`${0 + 30 + 15}deg`, `${2 * 360 + 30 + 15}deg`], | ||
}), | ||
}, | ||
], | ||
}, | ||
viewportStyle: { | ||
width: size, | ||
height: size, | ||
transform: [ | ||
{ | ||
translateY: index ? -size / 2 : 0, | ||
}, | ||
{ | ||
rotate: timer.interpolate({ inputRange, outputRange }), | ||
}, | ||
], | ||
}, | ||
lineStyle: { | ||
width: size, | ||
height: size, | ||
borderColor: color, | ||
borderWidth: size / 10, | ||
borderRadius: size / 2, | ||
}, | ||
}; | ||
}, [color, duration, index, size, timer]); | ||
|
||
return ( | ||
<Animated.View style={styles.layer}> | ||
<Animated.View style={layerStyle}> | ||
<Animated.View style={offsetContainerStyles} collapsable={false}> | ||
<Animated.View style={offsetContainerStyle} collapsable={false}> | ||
<Animated.View style={viewportStyle}> | ||
<Animated.View style={containerStyle} collapsable={false}> | ||
<Animated.View style={lineStyle} /> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,3 @@ | ||
export { | ||
default as ActivityIndicator, | ||
Props as ActivityIndicatorProps, | ||
defaultStyles as activityIndicatorStyles, | ||
} from './ActivityIndicator'; | ||
export { default as ActivityIndicator, Props as ActivityIndicatorProps } from './ActivityIndicator'; | ||
|
||
export { activityIndicatorStyles } from './utils'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { StyleSheet, ViewStyle } from 'react-native'; | ||
import type { ComponentStylePropWithVariants } from '../../types'; | ||
|
||
export const styles = { | ||
container: { | ||
justifyContent: 'center', | ||
alignItems: 'center', | ||
}, | ||
|
||
layer: { | ||
...StyleSheet.absoluteFillObject, | ||
|
||
justifyContent: 'center', | ||
alignItems: 'center', | ||
}, | ||
}; | ||
|
||
type CustomProps = { | ||
color?: string; | ||
animationScale?: string; | ||
}; | ||
|
||
export const activityIndicatorStyles: ComponentStylePropWithVariants<ViewStyle, '', CustomProps> = { | ||
color: 'colors.primary', | ||
animationScale: 'animation.scale', | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CircularExample has props
animatedValue
trackColor
- not required for circularvisible
- doesn't do anythingAlso, What is the use for indeterminateMaxWidth in Circular indicator?