Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

refactor(Button): enable loading state for button #253

Merged
merged 3 commits into from
Sep 16, 2024
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
13 changes: 10 additions & 3 deletions src/elements/Button/Button.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,15 @@ export const VariantsLoading = () => (
<DataList
data={variants}
renderItem={({ item: variant }) => (
<Button variant={variant} loading onPress={() => console.log(`tapped ${variant}`)}>
{variant}
</Button>
<Wrap if={variant === "outlineLight"} key={`variant_loading_${variant}`}>
<Flex backgroundColor="black100" p={1}>
<Wrap.Content>
<Button variant={variant} loading onPress={() => console.log(`tapped ${variant}`)}>
{variant}
</Button>
</Wrap.Content>
</Flex>
</Wrap>
)}
/>
)
Expand All @@ -118,6 +124,7 @@ export const TheFollowButton = () => {

return (
<List>
<FollowButton loading isFollowed={follow} onPress={() => setFollow((v) => !v)} />
<FollowButton isFollowed={follow} onPress={() => setFollow((v) => !v)} />
<FollowButton followCount={4} isFollowed={follow} onPress={() => setFollow((v) => !v)} />
<FollowButton followCount={40} isFollowed={follow} onPress={() => setFollow((v) => !v)} />
Expand Down
28 changes: 16 additions & 12 deletions src/elements/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,6 @@ export const Button = ({
}
})()

const spinnerColor = variant === "text" ? "blue100" : "white100"

const handlePress = (event: GestureResponderEvent) => {
if (onPress === undefined || onPress === null) {
return
Expand All @@ -145,6 +143,14 @@ export const Button = ({
borderColor: colors.disabled.border,
}
}

if (loading) {
return {
backgroundColor: colors.loading.bg,
borderColor: colors.loading.border,
}
}

return {
backgroundColor: interpolateColor(
pressAnimationProgress.value,
Expand All @@ -161,8 +167,9 @@ export const Button = ({

const textAnim = useAnimatedStyle(() => {
const colors = colorsForVariantAndState[variant]

if (loading) {
return { color: "rgba(0, 0, 0, 0)" }
return { color: colors.loading.text }
}

return {
Expand All @@ -174,6 +181,7 @@ export const Button = ({
textDecorationLine: pressAnimationProgress.value > 0 ? "underline" : "none",
}
})
const loaderColor = colorsForVariantAndState[variant].loading.loader

return (
<Pressable
Expand Down Expand Up @@ -213,46 +221,42 @@ export const Button = ({
<Spacer x={0.5} />
</Box>
) : null}

{iconPosition === "left" && !!icon ? (
<>
{icon}
<Spacer x={0.5} />
</>
) : null}

<AText
style={[{ width: Math.ceil(longestTextMeasurements.width) }, textStyle, textAnim]}
textAlign="center"
selectable={false}
>
{children}
</AText>

<MeasuredView setMeasuredState={setLongestTextMeasurements}>
<Text color="red" style={textStyle}>
{longestText ? longestText : children}
</Text>
</MeasuredView>

{iconPosition === "right" && !!icon ? (
{iconPosition === "right" && !!icon && (
<>
<Spacer x={0.5} />
{icon}
</>
) : null}
)}

{loading ? (
{loading && (
Copy link
Member

Choose a reason for hiding this comment

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

🤔 can't believe that this was the issue 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it wasn't we we missing the loader colors and the transparencies to the text too

Copy link
Member

Choose a reason for hiding this comment

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

I get that the colors were missing but what about the size of the button? It is not affected by the colors right?

<Box
position="absolute"
width="100%"
height="100%"
alignItems="center"
justifyContent="center"
>
<Spinner size={size} color={spinnerColor} />
<Spinner size={size} color={loaderColor} />
</Box>
) : null}
)}
</Flex>
</AFlex>
</Flex>
Expand Down
7 changes: 5 additions & 2 deletions src/elements/Button/FollowButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const FollowButton = ({
loading,
...restProps
}: FollowButtonProps) => {
const label = isFollowed ? "Following" : "Follow"
return (
<Button
variant={isFollowed ? "outline" : "outlineGray"}
Expand All @@ -28,9 +29,11 @@ export const FollowButton = ({
loading={loading}
{...restProps}
>
{!loading && (
{!!loading ? (
`${label} ${followCount && followCount > 1 ? formatLargeNumber(followCount, 1) : ""}`
) : (
<>
<Text variant="xs">{isFollowed ? "Following" : "Follow"}</Text>
<Text variant="xs">{label}</Text>
{!!followCount && followCount > 1 && (
<Text variant="xs" color="black60">
{" " + formatLargeNumber(followCount, 1)}
Expand Down
52 changes: 50 additions & 2 deletions src/elements/Button/colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { ButtonProps } from "./Button"
import { useColor } from "../../utils/hooks"
import { NoUndefined } from "../../utils/types"

type State = "disabled" | "pressed" | "active"
type State = "disabled" | "pressed" | "active" | "loading"

export const useColorsForVariantAndState = (): Record<
NoUndefined<ButtonProps["variant"]>,
Record<State, { bg: string; border: string; text: string }>
Record<State, { bg: string; border: string; text: string; loader?: string }>
> => {
const color = useColor()

Expand All @@ -15,6 +15,12 @@ export const useColorsForVariantAndState = (): Record<
disabled: { bg: color("black30"), border: color("black30"), text: color("onPrimaryHigh") },
pressed: { bg: color("blue100"), border: color("blue100"), text: color("onPrimaryHigh") },
active: { bg: color("primary"), border: color("primary"), text: color("onPrimaryHigh") },
loading: {
bg: color("black100"),
border: color("black100"),
text: "rgba(0, 0, 0, 0)",
loader: "white100",
},
},
fillLight: {
disabled: { bg: color("black30"), border: color("black30"), text: color("onPrimaryHigh") },
Expand All @@ -24,16 +30,34 @@ export const useColorsForVariantAndState = (): Record<
border: color("white100"),
text: color("black100"),
},
loading: {
bg: color("white100"),
border: color("white100"),
text: "rgba(0, 0, 0, 0)",
loader: "black100",
},
},
fillGray: {
disabled: { bg: color("black30"), border: color("black30"), text: color("white100") },
pressed: { bg: color("blue100"), border: color("blue100"), text: color("white100") },
active: { bg: color("black10"), border: color("black10"), text: color("black100") },
loading: {
bg: color("black10"),
border: color("black10"),
text: "rgba(0, 0, 0, 0)",
loader: "black100",
},
},
fillSuccess: {
disabled: { bg: color("blue100"), border: color("blue100"), text: color("white100") },
pressed: { bg: color("blue100"), border: color("blue100"), text: color("white100") },
active: { bg: color("blue10"), border: color("blue10"), text: color("white100") },
loading: {
bg: color("blue100"),
border: color("blue100"),
text: "rgba(0, 0, 0, 0)",
loader: "white100",
},
},
outline: {
disabled: {
Expand All @@ -47,6 +71,12 @@ export const useColorsForVariantAndState = (): Record<
border: color("black60"),
text: color("black100"),
},
loading: {
bg: color("white100"),
border: color("black60"),
text: "rgba(0, 0, 0, 0)",
loader: "black100",
},
},
outlineGray: {
disabled: {
Expand All @@ -60,6 +90,12 @@ export const useColorsForVariantAndState = (): Record<
border: color("black60"),
text: color("black100"),
},
loading: {
bg: color("white100"),
border: color("black30"),
text: "rgba(0, 0, 0, 0)",
loader: "black100",
},
},
outlineLight: {
disabled: {
Expand All @@ -73,11 +109,23 @@ export const useColorsForVariantAndState = (): Record<
border: color("white100"),
text: color("white100"),
},
loading: {
bg: "rgba(0,0,0,0)",
border: color("white100"),
text: "rgba(0, 0, 0, 0)",
loader: "white100",
},
},
text: {
disabled: { bg: "rgba(0, 0, 0, 0)", border: "rgba(0, 0, 0, 0)", text: color("black30") },
pressed: { bg: color("black10"), border: color("black10"), text: color("blue100") },
active: { bg: "rgba(0, 0, 0, 0)", border: "rgba(0, 0, 0, 0)", text: color("black100") },
loading: {
bg: color("white100"),
border: color("white100"),
text: "rgba(0, 0, 0, 0)",
loader: "blue100",
},
},
}
}