replace buttons

Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
This commit is contained in:
Charles de Dreuille
2025-06-20 14:58:52 +01:00
parent cb2ac11b1b
commit e2d70b7f5e
6 changed files with 82 additions and 74 deletions
+26 -18
View File
@@ -18,28 +18,36 @@ import { forwardRef, ElementRef } from 'react';
import { Avatar as AvatarPrimitive } from '@base-ui-components/react/avatar';
import clsx from 'clsx';
import { AvatarProps } from './types';
import { useStyles } from '../../hooks/useStyles';
/** @public */
export const Avatar = forwardRef<
ElementRef<typeof AvatarPrimitive.Root>,
AvatarProps
>(({ className, src, name, size = 'medium', ...props }, ref) => (
<AvatarPrimitive.Root
ref={ref}
className={clsx('canon-AvatarRoot', className)}
data-size={size}
{...props}
>
<AvatarPrimitive.Image className="canon-AvatarImage" src={src} />
<AvatarPrimitive.Fallback className="canon-AvatarFallback">
{(name || '')
.split(' ')
.map(word => word[0])
.join('')
.toLocaleUpperCase('en-US')
.slice(0, 2)}
</AvatarPrimitive.Fallback>
</AvatarPrimitive.Root>
));
>((props, ref) => {
const { className, src, name, size = 'medium', ...rest } = props;
const { classNames } = useStyles('Avatar', {
size,
});
return (
<AvatarPrimitive.Root
ref={ref}
className={clsx(classNames.root, className)}
data-size={size}
{...rest}
>
<AvatarPrimitive.Image className={classNames.image} src={src} />
<AvatarPrimitive.Fallback className={classNames.fallback}>
{(name || '')
.split(' ')
.map(word => word[0])
.join('')
.toLocaleUpperCase('en-US')
.slice(0, 2)}
</AvatarPrimitive.Fallback>
</AvatarPrimitive.Root>
);
});
Avatar.displayName = AvatarPrimitive.Root.displayName;
@@ -18,7 +18,7 @@ import clsx from 'clsx';
import { forwardRef, Ref } from 'react';
import { Button as RAButton } from 'react-aria-components';
import type { ButtonProps } from './types';
import { useStyles } from '../../definition';
import { useStyles } from '../../hooks/useStyles';
/** @public */
export const Button = forwardRef(
@@ -17,8 +17,8 @@
import clsx from 'clsx';
import { forwardRef, Ref } from 'react';
import { Button as RAButton } from 'react-aria-components';
import { useResponsiveValue } from '../../hooks/useResponsiveValue';
import type { ButtonIconProps } from './types';
import { useStyles } from '../../hooks/useStyles';
/** @public */
export const ButtonIcon = forwardRef(
@@ -32,15 +32,18 @@ export const ButtonIcon = forwardRef(
...rest
} = props;
const responsiveSize = useResponsiveValue(size);
const responsiveVariant = useResponsiveValue(variant);
const { classNames, dataAttributes } = useStyles('Button', {
size,
variant,
});
const { classNames: classNamesButtonIcon } = useStyles('ButtonIcon');
return (
<RAButton
className={clsx('canon-Button', 'canon-ButtonIcon', className)}
data-variant={responsiveVariant}
data-size={responsiveSize}
className={clsx(classNames.root, classNamesButtonIcon.root, className)}
ref={ref}
{...dataAttributes}
{...rest}
>
{icon}
@@ -17,8 +17,8 @@
import clsx from 'clsx';
import { forwardRef, Ref } from 'react';
import { Link as RALink } from 'react-aria-components';
import { useResponsiveValue } from '../../hooks/useResponsiveValue';
import type { ButtonLinkProps } from './types';
import { useStyles } from '../../hooks/useStyles';
/** @public */
export const ButtonLink = forwardRef(
@@ -33,15 +33,18 @@ export const ButtonLink = forwardRef(
...rest
} = props;
const responsiveSize = useResponsiveValue(size);
const responsiveVariant = useResponsiveValue(variant);
const { classNames, dataAttributes } = useStyles('Button', {
size,
variant,
});
const { classNames: classNamesButtonLink } = useStyles('ButtonLink');
return (
<RALink
className={clsx('canon-Button', 'canon-ButtonLink', className)}
data-variant={responsiveVariant}
data-size={responsiveSize}
className={clsx(classNames.root, classNamesButtonLink.root, className)}
ref={ref}
{...dataAttributes}
{...rest}
>
{iconStart}
+8 -3
View File
@@ -15,7 +15,7 @@
*/
import { useBreakpoint, breakpoints } from './useBreakpoint';
import { componentDefinitions } from '../utils/componentDefinitions';
import type { ComponentDefinitionName } from '../types';
import type { ComponentDefinitionName, ComponentClassNames } from '../types';
/**
* Resolve a responsive value based on the current breakpoint
@@ -61,9 +61,14 @@ function resolveResponsiveValue(
export function useStyles<T extends ComponentDefinitionName>(
componentName: T,
props: Record<string, any> = {},
) {
): {
classNames: ComponentClassNames<T>;
dataAttributes: Record<string, string>;
resolvedProps: Record<string, string>;
} {
const { breakpoint } = useBreakpoint();
const classNames = componentDefinitions[componentName].classNames;
const classNames = componentDefinitions[componentName]
.classNames as ComponentClassNames<T>;
// Resolve responsive values and generate data attributes
const dataAttributes: Record<string, string> = {};
@@ -17,12 +17,40 @@
import type { ComponentDefinition } from '../types';
export const componentDefinitions = {
// Layout Components
Avatar: {
classNames: {
root: 'canon-AvatarRoot',
image: 'canon-AvatarImage',
fallback: 'canon-AvatarFallback',
},
dataAttributes: {
size: ['small', 'medium', 'large'] as const,
},
},
Box: {
classNames: {
root: 'canon-Box',
},
},
Button: {
classNames: {
root: 'canon-Button',
},
dataAttributes: {
size: ['small', 'medium', 'large'] as const,
variant: ['primary', 'secondary', 'ghost'] as const,
},
},
ButtonIcon: {
classNames: {
root: 'canon-ButtonIcon',
},
},
ButtonLink: {
classNames: {
root: 'canon-ButtonLink',
},
},
Container: {
classNames: {
@@ -66,33 +94,6 @@ export const componentDefinitions = {
},
},
// Form Components
Button: {
classNames: {
root: 'canon-Button',
},
dataAttributes: {
size: ['small', 'medium', 'large'] as const,
variant: ['primary', 'secondary', 'ghost'] as const,
},
},
ButtonIcon: {
classNames: {
root: 'canon-ButtonIcon',
},
dataAttributes: {
size: ['small', 'medium', 'large'] as const,
variant: ['primary', 'secondary', 'ghost'] as const,
},
},
ButtonLink: {
classNames: {
root: 'canon-ButtonLink',
},
},
TextField: {
classNames: {
root: 'canon-TextField',
@@ -223,18 +224,6 @@ export const componentDefinitions = {
},
},
Avatar: {
classNames: {
root: 'canon-Avatar',
image: 'canon-Avatar-image',
fallback: 'canon-Avatar-fallback',
indicator: 'canon-Avatar-indicator',
},
dataAttributes: {
size: ['small', 'medium', 'large'] as const,
},
},
Icon: {
classNames: {
root: 'canon-Icon',