diff --git a/.changeset/strange-months-thank.md b/.changeset/strange-months-thank.md
new file mode 100644
index 00000000..5054d96b
--- /dev/null
+++ b/.changeset/strange-months-thank.md
@@ -0,0 +1,5 @@
+---
+"@cambly/syntax-core": minor
+---
+
+Cambio: add Avatar & AvatarGroup updates
diff --git a/packages/syntax-core/package.json b/packages/syntax-core/package.json
index b2634888..55ceb8da 100644
--- a/packages/syntax-core/package.json
+++ b/packages/syntax-core/package.json
@@ -14,7 +14,7 @@
"scripts": {
"build": "tsup",
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist",
- "dev": "tsup --watch",
+ "dev": "NODE_OPTIONS=--max_old_space_size=4096 tsup --watch",
"lint": "TIMING=1 eslint \"src/**/*.ts*\" --max-warnings 0",
"stylelint": "stylelint \"**/*.css\"",
"stylelint:fix": "npm run stylelint --fix",
diff --git a/packages/syntax-core/src/Avatar/Avatar.module.css b/packages/syntax-core/src/Avatar/Avatar.module.css
index b4410398..0f46ad2b 100644
--- a/packages/syntax-core/src/Avatar/Avatar.module.css
+++ b/packages/syntax-core/src/Avatar/Avatar.module.css
@@ -8,9 +8,16 @@
background-size: cover;
background-repeat: no-repeat;
border-radius: 50%;
+}
+
+.avatarImageClassic {
border: 2px solid #fff;
}
+.avatarImageOutlineCambio {
+ border: 2px solid var(--color-cambio-gray-100);
+}
+
.sm {
width: 24px;
height: 24px;
@@ -30,3 +37,23 @@
width: 128px;
height: 129px;
}
+
+.smCambio {
+ width: 32px;
+ height: 32px;
+}
+
+.mdCambio {
+ width: 48px;
+ height: 48px;
+}
+
+.lgCambio {
+ width: 64px;
+ height: 64px;
+}
+
+.xlCambio {
+ width: 64px;
+ height: 64px;
+}
diff --git a/packages/syntax-core/src/Avatar/Avatar.tsx b/packages/syntax-core/src/Avatar/Avatar.tsx
index 92aff5b3..63fc36af 100644
--- a/packages/syntax-core/src/Avatar/Avatar.tsx
+++ b/packages/syntax-core/src/Avatar/Avatar.tsx
@@ -3,6 +3,7 @@ import classNames from "classnames";
import styles from "./Avatar.module.css";
import Box from "../Box/Box";
import { useAvatarGroup } from "../AvatarGroup/AvatarGroup";
+import { useTheme } from "../ThemeProvider/ThemeProvider";
const sizeToIconStyles = {
sm: { bottom: 6, marginInlineEnd: 2, height: 4, width: 4 },
@@ -11,30 +12,51 @@ const sizeToIconStyles = {
xl: { bottom: 12, marginInlineEnd: 12, height: 16, width: 16 },
} as const;
-const sizeToMargin = {
+const sizeToMarginClassic = {
sm: -16,
md: -28,
lg: -48,
xl: -88,
} as const;
+const sizeToMarginCambio = {
+ sm: -12,
+ md: -20,
+ lg: -28,
+ xl: -28,
+} as const;
+
function AvatarInternal({
accessibilityLabel,
icon,
+ outline,
size = "md",
src,
}: {
accessibilityLabel: string;
icon?: React.ReactElement;
+ outline?: boolean;
size?: "sm" | "md" | "lg" | "xl";
src: string;
}): ReactElement {
+ const { themeName } = useTheme();
+
return (
-
+
{icon && (
@@ -81,11 +103,18 @@ const Avatar = ({
/**
* Size of the avatar.
*
+ * Classic:
* * `sm`: 24px
* * `md`: 40px
* * `lg`: 72px
* * `xl`: 128px
*
+ * Cambio:
+ * * `sm`: 32px
+ * * `md`: 48px
+ * * `lg`: 64px
+ * * `xl`: 64px (deprecated, maps to `lg` in Cambio)
+ *
* @defaultValue `md`
*/
size?: "sm" | "md" | "lg" | "xl";
@@ -95,6 +124,7 @@ const Avatar = ({
src: string;
}): JSX.Element => {
const avatarGroupContext = useAvatarGroup();
+ const { themeName } = useTheme();
if (avatarGroupContext !== null) {
return (
@@ -102,7 +132,10 @@ const Avatar = ({
position="relative"
dangerouslySetInlineStyle={{
__style: {
- marginInlineEnd: sizeToMargin[avatarGroupContext.size],
+ marginInlineEnd:
+ themeName === "cambio"
+ ? sizeToMarginCambio[avatarGroupContext.size]
+ : sizeToMarginClassic[avatarGroupContext.size],
},
}}
>
@@ -116,6 +149,7 @@ const Avatar = ({
diff --git a/packages/syntax-core/src/AvatarGroup/AvatarGroup.tsx b/packages/syntax-core/src/AvatarGroup/AvatarGroup.tsx
index 59718b88..1f56955e 100644
--- a/packages/syntax-core/src/AvatarGroup/AvatarGroup.tsx
+++ b/packages/syntax-core/src/AvatarGroup/AvatarGroup.tsx
@@ -5,8 +5,14 @@ import {
type ReactElement,
} from "react";
import Box from "../Box/Box";
+import { useTheme } from "../ThemeProvider/ThemeProvider";
-type Size = "sm" | "md" | "lg" | "xl";
+type Size =
+ | "sm"
+ | "md"
+ | "lg"
+ /* `xl` is deprecated and mapped to `lg` in Cambio */
+ | "xl";
type Orientation = "standard" | "reverse";
type AvatarGroupContextType = {
@@ -43,11 +49,18 @@ export default function AvatarGroup({
/**
* Size of the avatars in the AvatarGroup.
*
+ * Classic:
* * `sm`: 24px
* * `md`: 40px
* * `lg`: 72px
* * `xl`: 128px
*
+ * Cambio:
+ * * `sm`: 32px
+ * * `md`: 48px
+ * * `lg`: 64px
+ * * `xl`: 64px (deprecated, maps to `lg` in Cambio)
+ *
* @defaultValue `md`
*/
size?: Size;
@@ -65,8 +78,11 @@ export default function AvatarGroup({
*/
children: ReactNode;
}): ReactElement {
+ const { themeName } = useTheme();
+ const parsedSize = themeName === "cambio" && size === "xl" ? "lg" : size;
+
return (
-
+
(function Box(
ref,
): ReactElement {
const { as: BoxElement = "div", children, ...boxProps } = props;
+ const { themeName } = useTheme();
const {
// Classname
@@ -492,6 +503,11 @@ const Box = forwardRef(function Box(
...maybePassThroughProps
} = boxProps;
+ const parsedRounding =
+ themeName === "cambio" && rounding && ["md", "lg", "xl"].includes(rounding)
+ ? "sm"
+ : rounding;
+
const parsedProps = {
className: classNames(
styles.box,
@@ -575,7 +591,9 @@ const Box = forwardRef(function Box(
smJustifyContent && styles[`justifyContent${smJustifyContent}Small`],
lgJustifyContent && styles[`justifyContent${lgJustifyContent}Large`],
position && position !== "static" && styles[position],
- rounding && rounding !== "none" && roundingStyles[`rounding${rounding}`],
+ parsedRounding &&
+ parsedRounding !== "none" &&
+ roundingStyles[`rounding${parsedRounding}`],
overflow && styles[`overflow${overflow}`],
overflowX && styles[`overflowX${overflowX}`],
overflowY && styles[`overflowY${overflowY}`],
diff --git a/packages/syntax-core/src/ThemeProvider/ThemeProvider.tsx b/packages/syntax-core/src/ThemeProvider/ThemeProvider.tsx
index 601dcf98..1fb8f42e 100644
--- a/packages/syntax-core/src/ThemeProvider/ThemeProvider.tsx
+++ b/packages/syntax-core/src/ThemeProvider/ThemeProvider.tsx
@@ -15,10 +15,10 @@ ThemeContext.displayName = "ThemeContext";
const classicToCambioKeyLookup = {
"color-base-black": "color-cambio-black",
"color-base-destructive-100": "color-cambio-destructive-100",
- "color-base-destructive-200": undefined, // Deprecated - to be deleted
+ "color-base-destructive-200": "color-cambio-destructive-300",
"color-base-destructive-300": "color-cambio-destructive-300",
"color-base-destructive-700": "color-cambio-destructive-700",
- "color-base-destructive-800": undefined, // Deprecated - to be deleted
+ "color-base-destructive-800": "color-cambio-destructive-900",
"color-base-destructive-900": "color-cambio-destructive-900",
"color-base-gray-10": "color-cambio-gray-370",
"color-base-gray-30": "color-cambio-gray-370",
@@ -43,10 +43,10 @@ const classicToCambioKeyLookup = {
"color-base-primary-800": "color-cambio-gray-800",
"color-base-primary-900": "color-cambio-gray-900",
"color-base-success-100": "color-cambio-success-100",
- "color-base-success-200": undefined, // Deprecated - to be deleted
+ "color-base-success-200": "color-cambio-success-300",
"color-base-success-300": "color-cambio-success-300",
"color-base-success-700": "color-cambio-success-700",
- "color-base-success-800": undefined, // Deprecated - to be deleted
+ "color-base-success-800": "color-cambio-success-900",
"color-base-success-900": "color-cambio-success-900",
"color-base-purple-100": undefined, // Deprecated - to be deleted
"color-base-purple-200": undefined, // Deprecated - to be deleted