Skip to content

Commit

Permalink
Button/IconButton/LinkButton: add 'on' lightBackground or darkBackgro…
Browse files Browse the repository at this point in the history
…und prop (#333)
  • Loading branch information
christianvuerings committed Mar 18, 2024
1 parent 44de733 commit 941041f
Show file tree
Hide file tree
Showing 14 changed files with 278 additions and 59 deletions.
5 changes: 5 additions & 0 deletions .changeset/fluffy-files-press.md
@@ -0,0 +1,5 @@
---
"@cambly/syntax-core": minor
---

Button/Chip/IconButton/LinkButton: add 'on' lightBackground or darkBackground prop (Cambio only)
2 changes: 1 addition & 1 deletion packages/syntax-core/package.json
Expand Up @@ -14,7 +14,7 @@
"scripts": {
"build": "tsup",
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist",
"dev": "NODE_OPTIONS=--max_old_space_size=4096 tsup --watch",
"dev": "NODE_OPTIONS=--max_old_space_size=8192 tsup --watch",
"lint": "TIMING=1 eslint \"src/**/*.ts*\" --max-warnings 0",
"stylelint": "stylelint \"**/*.css\"",
"stylelint:fix": "npm run stylelint --fix",
Expand Down
32 changes: 32 additions & 0 deletions packages/syntax-core/src/Button/Button.stories.tsx
@@ -1,6 +1,7 @@
import { type StoryObj, type Meta } from "@storybook/react";
import Button from "./Button";
import FavoriteBorder from "@mui/icons-material/FavoriteBorder";
import Box from "../Box/Box";

export default {
title: "Components/Button",
Expand All @@ -11,6 +12,20 @@ export default {
url: "https://www.figma.com/file/p7LKna9JMU0JEkcKamzs53/Cambly-Design-System-(Draft)?node-id=994%3A2346",
},
},
args: {
text: "Call to action",
color: "primary",
on: "lightBackground",
size: "md",
disabled: false,
loading: false,
fullWidth: false,
"data-testid": "",
loadingText: "",
accessibilityLabel: "",
tooltip: "",
type: "button",
},
argTypes: {
color: {
options: [
Expand All @@ -29,6 +44,10 @@ export default {
],
control: { type: "radio" },
},
on: {
options: ["lightBackground", "darkBackground"],
control: { type: "radio" },
},
size: {
options: ["sm", "md", "lg"],
control: { type: "radio" },
Expand All @@ -43,12 +62,25 @@ export default {
control: "boolean",
},
onClick: { action: "clicked" },
type: {
options: ["button", "submit", "reset"],
},
},
tags: ["autodocs"],
} as Meta<typeof Button>;

export const Default: StoryObj<typeof Button> = {
args: { text: "Call to action" },
render: (args) => {
return (
<Box
backgroundColor={args.on === "lightBackground" ? "white" : "black"}
padding={2}
>
<Button {...args} />
</Box>
);
},
};
export const Small: StoryObj<typeof Button> = {
args: { ...Default.args, size: "sm" },
Expand Down
13 changes: 10 additions & 3 deletions packages/syntax-core/src/Button/Button.tsx
Expand Up @@ -107,6 +107,12 @@ type ButtonProps = {
* Note: endIcon is not supported in the Cambio theme
*/
endIcon?: React.ComponentType<{ className?: string }>;
/**
* Indicate whether the button renders on a light or dark background. Changes the color of the button (Cambio only)
*
* @defaulValue `lightBackground`
*/
on?: "lightBackground" | "darkBackground";
/**
* The callback to be called when the button is clicked
*/
Expand All @@ -116,7 +122,7 @@ type ButtonProps = {
*/
tooltip?: string;
/**
* The type you want to set for the primitive <button/>
* The type you want to set for the primitive `<button/>`
*/
type?: "button" | "submit" | "reset";
};
Expand All @@ -138,6 +144,7 @@ const Button = forwardRef<HTMLButtonElement, ButtonProps>(
fullWidth = false,
startIcon: StartIcon,
endIcon: EndIcon,
on = "lightBackground",
onClick,
tooltip,
type = "button",
Expand All @@ -150,12 +157,12 @@ const Button = forwardRef<HTMLButtonElement, ButtonProps>(
const foregroundColorClass =
themeName === "classic"
? classicForegroundColor(classicColor(color))
: cambioForegroundColor(cambioColor(color));
: cambioForegroundColor(cambioColor(color), on);

const backgroundColorClass =
themeName === "classic"
? classicBackgroundColor(classicColor(color))
: cambioBackgroundColor(cambioColor(color));
: cambioBackgroundColor(cambioColor(color), on);

return (
<button
Expand Down
8 changes: 8 additions & 0 deletions packages/syntax-core/src/Chip/Chip.module.css
Expand Up @@ -35,10 +35,18 @@
background-color: var(--color-cambio-gray-370);
}

.deselectedChipCambioOnDarkBackground {
background-color: var(--color-cambio-gray-870);
}

.selectedChipCambio {
background-color: var(--color-cambio-gray-800);
}

.selectedChipCambioOnDarkBackground {
background-color: var(--color-cambio-gray-200);
}

.icon {
/* stylelint-disable-next-line declaration-no-important -- Need to use !important to override MUI icon sizes */
height: 24px !important;
Expand Down
22 changes: 20 additions & 2 deletions packages/syntax-core/src/Chip/Chip.stories.tsx
Expand Up @@ -13,7 +13,17 @@ export default {
url: "https://www.figma.com/file/p7LKna9JMU0JEkcKamzs53/%F0%9F%93%90-Syntax?type=design&node-id=6156%3A25032&mode=design&t=SSblm5y2vyrOKil1-1",
},
},
args: {
selected: false,
text: "text on chip",
size: "sm",
on: "lightBackground",
},
argTypes: {
on: {
options: ["lightBackground", "darkBackground"],
control: { type: "radio" },
},
selected: {
control: "boolean",
},
Expand All @@ -30,8 +40,16 @@ export const Default: StoryObj<typeof Chip> = {
text: "text on chip",
selected: false,
},
/* eslint-disable-next-line react/jsx-props-no-spreading */
render: ({ ...args }) => <Chip {...args} />,
render: (args) => {
return (
<Box
backgroundColor={args.on === "lightBackground" ? "white" : "black"}
padding={2}
>
<Chip {...args} />
</Box>
);
},
};

const ChipInteractive = () => {
Expand Down
54 changes: 50 additions & 4 deletions packages/syntax-core/src/Chip/Chip.tsx
@@ -1,11 +1,35 @@
import React, { forwardRef } from "react";
import React, { forwardRef, useMemo } from "react";
import classnames from "classnames";
import Typography from "../Typography/Typography";
import Box from "../Box/Box";
import styles from "./Chip.module.css";
import useIsHydrated from "../useIsHydrated";
import { useTheme } from "../ThemeProvider/ThemeProvider";

function typographyColor({
themeName,
selected,
on,
}: {
themeName: "cambio" | "classic";
selected: boolean;
on: "lightBackground" | "darkBackground";
}): "white" | "gray900" {
if (themeName === "cambio" && on === "darkBackground") {
if (selected) {
return "gray900";
} else {
return "white";
}
} else {
if (selected) {
return "white";
} else {
return "gray900";
}
}
}

type ChipProps = {
/**
* If true, the chip will be disabled.
Expand Down Expand Up @@ -40,6 +64,12 @@ type ChipProps = {
* The text to be displayed on the chip
*/
text: string;
/**
* Indicate whether the badge renders on a light or dark background. Changes the color of the chip (Cambio only)
*
* @defaulValue `lightBackground`
*/
on?: "lightBackground" | "darkBackground";
/**
* The callback to be called when the chip is clicked
*/
Expand All @@ -62,6 +92,7 @@ const Chip = forwardRef<HTMLButtonElement, ChipProps>(
"data-testid": dataTestId,
size = "sm",
text,
on = "lightBackground",
onChange,
icon: Icon,
dangerouslyForceFocusStyles,
Expand All @@ -73,17 +104,27 @@ const Chip = forwardRef<HTMLButtonElement, ChipProps>(
const isHydrated = useIsHydrated();
const disabled = !isHydrated || disabledProp;

const selectedChipCambioStyle =
on === "lightBackground"
? styles.selectedChipCambio
: styles.selectedChipCambioOnDarkBackground;

const deselectedChipCambioStyle =
on === "lightBackground"
? styles.deselectedChipCambio
: styles.deselectedChipCambioOnDarkBackground;

const chipStyles = classnames(
styles.chip,
themeName === "classic" ? styles.chipClassic : styles.chipCambio,
styles[transformedSize],
{
[themeName === "classic"
? styles.selectedChip
: styles.selectedChipCambio]: selected,
: selectedChipCambioStyle]: selected,
[themeName === "classic"
? styles.deselectedChip
: styles.deselectedChipCambio]: !selected,
: deselectedChipCambioStyle]: !selected,
[styles.disabled]: disabled,
[styles.forceFocus]: dangerouslyForceFocusStyles,
},
Expand All @@ -96,6 +137,11 @@ const Chip = forwardRef<HTMLButtonElement, ChipProps>(
["lg"]: 300,
} as const;

const color = useMemo(
() => typographyColor({ themeName, selected, on }),
[themeName, selected, on],
);

return (
<button
className={chipStyles}
Expand All @@ -112,7 +158,7 @@ const Chip = forwardRef<HTMLButtonElement, ChipProps>(
size={
themeName === "classic" ? typographySize[transformedSize] : 100
}
color={selected ? "white" : "gray900"}
color={color}
>
{text}
</Typography>
Expand Down
7 changes: 0 additions & 7 deletions packages/syntax-core/src/IconButton/IconButton.module.css
Expand Up @@ -117,10 +117,3 @@
/* stylelint-disable-next-line declaration-no-important -- Need to use !important to override MUI icon sizes */
width: 32px !important;
}

.xlIconCambio {
/* stylelint-disable-next-line declaration-no-important -- Need to use !important to override MUI icon sizes */
height: 40px !important;
/* stylelint-disable-next-line declaration-no-important -- Need to use !important to override MUI icon sizes */
width: 40px !important;
}
26 changes: 26 additions & 0 deletions packages/syntax-core/src/IconButton/IconButton.stories.tsx
Expand Up @@ -2,6 +2,7 @@ import { type StoryObj, type Meta } from "@storybook/react";
import IconButton from "./IconButton";
import FavoriteBorder from "@mui/icons-material/FavoriteBorder";
import Star from "@mui/icons-material/Star";
import Box from "../Box/Box";

export default {
title: "Components/IconButton",
Expand All @@ -12,6 +13,15 @@ export default {
url: "https://www.figma.com/file/p7LKna9JMU0JEkcKamzs53/Cambly-Design-System?node-id=1007%3A4105",
},
},
args: {
color: "primary",
on: "lightBackground",
size: "md",
disabled: false,
"data-testid": "",
accessibilityLabel: "",
tooltip: "",
},
argTypes: {
color: {
options: [
Expand All @@ -37,12 +47,28 @@ export default {
disabled: {
control: "boolean",
},
on: {
options: ["lightBackground", "darkBackground"],
control: { type: "radio" },
},
onClick: { action: "clicked" },
},
tags: ["autodocs"],
} as Meta<typeof IconButton>;

export const Default: StoryObj<typeof IconButton> = {
args: { accessibilityLabel: "Star", tooltip: "Demo title", icon: Star },

render: (args) => {
return (
<Box
backgroundColor={args.on === "lightBackground" ? "white" : "black"}
padding={2}
>
<IconButton {...args} />
</Box>
);
},
};
export const Small: StoryObj<typeof IconButton> = {
args: { ...Default.args, size: "sm" },
Expand Down
12 changes: 9 additions & 3 deletions packages/syntax-core/src/IconButton/IconButton.tsx
Expand Up @@ -25,7 +25,6 @@ const cambioIconSize = {
sm: styles.smIconCambio,
md: styles.mdIconCambio,
lg: styles.lgIconCambio,
xl: styles.xlIconCambio,
};

type IconButtonProps = {
Expand Down Expand Up @@ -90,6 +89,12 @@ type IconButtonProps = {
* @defaultValue false
*/
disabled?: boolean;
/**
* Indicate whether the button renders on a light or dark background. Changes the color of the button (Cambio only)
*
* @defaulValue `lightBackground`
*/
on?: "lightBackground" | "darkBackground";
/**
* The callback to be called when the button is clicked
*/
Expand All @@ -113,6 +118,7 @@ const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(
icon: Icon,
size = "md",
tooltip,
on = "lightBackground",
onClick,
}: IconButtonProps,
ref,
Expand All @@ -123,12 +129,12 @@ const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(
const foregroundColorClass =
themeName === "classic"
? classicForegroundColor(classicColor(color))
: cambioForegroundColor(cambioColor(color));
: cambioForegroundColor(cambioColor(color), on);

const backgroundColorClass =
themeName === "classic"
? classicBackgroundColor(classicColor(color))
: cambioBackgroundColor(cambioColor(color));
: cambioBackgroundColor(cambioColor(color), on);

return (
<button
Expand Down

0 comments on commit 941041f

Please sign in to comment.