Skip to content

Commit

Permalink
feat(Button): add link.bare variant, enable style override and styl…
Browse files Browse the repository at this point in the history
…e combination

- Add text.bare variant to IButtonVariant type
- Add special case in getButtonViewStyle for text.bare that removes padding and decorations
- Keep existing button variants and their styling intact
- Use text.bare variant in Profile screen's Edit button

This allows for buttons without padding while maintaining the existing button system.
  • Loading branch information
lourou committed Jan 16, 2025
1 parent f54afbe commit 25f268a
Show file tree
Hide file tree
Showing 6 changed files with 194 additions and 79 deletions.
1 change: 1 addition & 0 deletions design-system/Button/Button.props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export type IButtonVariant =
| "outline"
| "fill"
| "link"
| "link.bare"
/** @deprecated */
| "secondary"
| "secondary-danger"
Expand Down
49 changes: 32 additions & 17 deletions design-system/Button/Button.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,21 @@ export const getButtonViewStyle =
variant,
size,
action,
pressed = false,
pressed,
disabled = false,
}: IButtonStyleProps) =>
(theme: Theme): ViewStyle => {
const { spacing, colors, borderRadius } = theme;

const style: ViewStyle = {
}: {
variant: IButtonVariant;
size: IButtonSize;
action: IButtonAction;
pressed: boolean;
disabled?: boolean;
}) =>
({ spacing, colors, borderRadius }: Theme): ViewStyle => {
const baseStyle: ViewStyle = {
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
justifyContent: "center",
gap: spacing.xxs,
borderRadius: borderRadius.sm,
overflow: "hidden",
paddingVertical:
Expand All @@ -53,37 +58,47 @@ export const getButtonViewStyle =
size === "md" || size === "sm" ? spacing.xs : spacing.sm,
};

// Special case for bare link text buttons - no padding or other decorations
if (variant === "link.bare") {
return {
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
gap: spacing.xxs,
};
}

if (action === "primary") {
switch (variant) {
case "fill":
style.backgroundColor = colors.fill.primary;
baseStyle.backgroundColor = colors.fill.primary;
if (pressed) {
style.backgroundColor = colors.fill.secondary;
baseStyle.backgroundColor = colors.fill.secondary;
}
if (disabled) {
style.backgroundColor = colors.fill.tertiary;
baseStyle.backgroundColor = colors.fill.tertiary;
}
break;

case "outline":
style.borderWidth = 1;
style.borderColor = colors.border.secondary;
style.backgroundColor = "transparent";
baseStyle.borderWidth = 1;
baseStyle.borderColor = colors.border.secondary;
baseStyle.backgroundColor = "transparent";
if (pressed) {
style.backgroundColor = colors.fill.minimal;
baseStyle.backgroundColor = colors.fill.minimal;
}
break;

case "link":
case "text":
style.backgroundColor = "transparent";
// Put back when we're done refactoring all the variant="text" button
// if (pressed) {
// style.backgroundColor = colors.fill.minimal;
// }
// Temporary opacity change for the variant="text" button
baseStyle.backgroundColor = "transparent";
if (pressed) {
style.opacity = 0.8;
baseStyle.opacity = 0.8;
}
break;

Expand All @@ -92,7 +107,7 @@ export const getButtonViewStyle =
}
}

return style;
return baseStyle;
};

export const getButtonTextStyle =
Expand Down
89 changes: 50 additions & 39 deletions design-system/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,48 +52,54 @@ export function Button(props: IButtonProps) {

const variant: IButtonVariant = props.variant ?? "fill";

const $viewStyle = useCallback(
({ pressed }: PressableStateCallbackType): StyleProp<ViewStyle> => {
return [
themed(
getButtonViewStyle({ variant, size, action: "primary", pressed })
),
$viewStyleOverride,
pressed && $pressedViewStyleOverride,
disabled && $disabledViewStyleOverride,
];
},
[
themed,
variant,
size,
const $viewStyle = useMemo(
() => [
themed(
getButtonViewStyle({ variant, size, action: "primary", pressed: false })
),
$viewStyleOverride,
],
[themed, variant, size, $viewStyleOverride]
);

const $pressedViewStyle = useMemo(
() => [
themed(
getButtonViewStyle({ variant, size, action: "primary", pressed: true })
),
$pressedViewStyleOverride,
$disabledViewStyleOverride,
disabled,
]
],
[themed, variant, size, $pressedViewStyleOverride]
);

const $textStyle = useCallback(
({ pressed }: PressableStateCallbackType): StyleProp<TextStyle> => {
return [
themed(
getButtonTextStyle({ variant, size, action: "primary", pressed })
),
$textStyleOverride,
pressed && $pressedTextStyleOverride,
disabled && $disabledTextStyleOverride,
];
},
[
themed,
variant,
size,
const $disabledViewStyle = useMemo(
() => [$disabledViewStyleOverride],
[$disabledViewStyleOverride]
);

const $combinedTextStyle = useMemo(
() => [
themed(
getButtonTextStyle({ variant, size, action: "primary", pressed: false })
),
$textStyleOverride,
],
[themed, variant, size, $textStyleOverride]
);

const $pressedTextStyle = useMemo(
() => [
themed(
getButtonTextStyle({ variant, size, action: "primary", pressed: true })
),
$pressedTextStyleOverride,
$disabledTextStyleOverride,
disabled,
]
],
[themed, variant, size, $pressedTextStyleOverride]
);

const $disabledTextStyle = useMemo(
() => [$disabledTextStyleOverride],
[$disabledTextStyleOverride]
);

const handlePress = useCallback(
Expand All @@ -117,7 +123,10 @@ export function Button(props: IButtonProps) {

return (
<Pressable
style={$viewStyle}
style={({ pressed }) => [
pressed ? $pressedViewStyle : $viewStyle,
disabled && $disabledViewStyle,
]}
accessibilityRole="button"
accessibilityState={{ disabled: !!disabled }}
onPress={handlePress}
Expand All @@ -139,7 +148,6 @@ export function Button(props: IButtonProps) {
/>
)}

{/* @deprecated stuff */}
{!!_icon && (
<Icon
icon={_icon}
Expand All @@ -157,7 +165,10 @@ export function Button(props: IButtonProps) {
tx={tx}
text={title ?? text}
txOptions={txOptions}
style={$textStyle(state)}
style={[
state.pressed ? $pressedTextStyle : $combinedTextStyle,
disabled && $disabledTextStyle,
]}
>
{children}
</Text>
Expand Down
29 changes: 29 additions & 0 deletions features/profiles/utils/__tests__/formatUsername.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { formatUsername } from "../formatUsername";

describe("formatUsername", () => {
it("should return undefined when no username provided", () => {
const result = formatUsername(undefined);
expect(result).toBeUndefined();
});

it("should format .conversedev.eth username by extracting first part and adding @ prefix", () => {
const result = formatUsername("louisdev.conversedev.eth");
expect(result).toBe("@louisdev");
});

it("should format .converse.xyz username by extracting first part and adding @ prefix", () => {
const result = formatUsername("louisdev.converse.xyz");
expect(result).toBe("@louisdev");
});

it("should return undefined for non-Converse usernames", () => {
expect(formatUsername("louisdev.eth")).toBeUndefined();
expect(formatUsername("louisdev")).toBeUndefined();
expect(formatUsername("@louisdev")).toBeUndefined();
});

it("should return undefined for empty string", () => {
const result = formatUsername("");
expect(result).toBeUndefined();
});
});
26 changes: 26 additions & 0 deletions features/profiles/utils/formatUsername.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* Formats usernames from Converse domains by extracting the username part and adding @ prefix
* Returns undefined for non-Converse usernames
* @param username - The username to format
* @returns The formatted username with @ prefix if it's a Converse username, undefined otherwise
*/
export function formatUsername(
username: string | undefined
): string | undefined {
if (!username) return undefined;

// Check if it's a Converse username (either domain)
if (
username.endsWith(".conversedev.eth") ||
username.endsWith(".converse.xyz")
) {
// Extract everything before the domain
const cleanUsername = username
.replace(/\.conversedev\.eth$/, "")
.replace(/\.converse\.xyz$/, "");
return `@${cleanUsername}`;
}

// Return undefined for non-Converse usernames
return undefined;
}
Loading

0 comments on commit 25f268a

Please sign in to comment.