Update
Signed-off-by: Charles de Dreuille <charles.dedreuille@gmail.com>
This commit is contained in:
@@ -22,6 +22,7 @@ import {
|
||||
import clsx from 'clsx';
|
||||
import { FieldLabel } from '../FieldLabel';
|
||||
import { FieldError } from '../FieldError';
|
||||
import { useStyles } from '../../hooks/useStyles';
|
||||
|
||||
import type { RadioGroupProps, RadioProps } from './types';
|
||||
|
||||
@@ -40,6 +41,8 @@ export const RadioGroup = forwardRef<HTMLDivElement, RadioGroupProps>(
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
const { classNames } = useStyles('RadioGroup');
|
||||
|
||||
useEffect(() => {
|
||||
if (!label && !ariaLabel && !ariaLabelledBy) {
|
||||
console.warn(
|
||||
@@ -54,7 +57,7 @@ export const RadioGroup = forwardRef<HTMLDivElement, RadioGroupProps>(
|
||||
|
||||
return (
|
||||
<AriaRadioGroup
|
||||
className={clsx('canon-RadioGroup', className)}
|
||||
className={clsx(classNames.root, className)}
|
||||
aria-label={ariaLabel}
|
||||
aria-labelledby={ariaLabelledBy}
|
||||
{...rest}
|
||||
@@ -65,7 +68,7 @@ export const RadioGroup = forwardRef<HTMLDivElement, RadioGroupProps>(
|
||||
secondaryLabel={secondaryLabelText}
|
||||
description={description}
|
||||
/>
|
||||
<div className="canon-RadioGroupContent">{children}</div>
|
||||
<div className={classNames.content}>{children}</div>
|
||||
<FieldError />
|
||||
</AriaRadioGroup>
|
||||
);
|
||||
@@ -78,8 +81,14 @@ RadioGroup.displayName = 'RadioGroup';
|
||||
export const Radio = forwardRef<HTMLLabelElement, RadioProps>((props, ref) => {
|
||||
const { className, ...rest } = props;
|
||||
|
||||
const { classNames } = useStyles('RadioGroup');
|
||||
|
||||
return (
|
||||
<AriaRadio className={clsx('canon-Radio', className)} {...rest} ref={ref} />
|
||||
<AriaRadio
|
||||
className={clsx(classNames.radio, className)}
|
||||
{...rest}
|
||||
ref={ref}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -17,53 +17,70 @@
|
||||
import { forwardRef } from 'react';
|
||||
import { ScrollArea as ScrollAreaPrimitive } from '@base-ui-components/react/scroll-area';
|
||||
import clsx from 'clsx';
|
||||
import { useStyles } from '../../hooks/useStyles';
|
||||
|
||||
const ScrollAreaRoot = forwardRef<
|
||||
React.ElementRef<typeof ScrollAreaPrimitive.Root>,
|
||||
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Root>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<ScrollAreaPrimitive.Root
|
||||
ref={ref}
|
||||
className={clsx('canon-ScrollAreaRoot', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
>(({ className, ...props }, ref) => {
|
||||
const { classNames } = useStyles('ScrollArea');
|
||||
|
||||
return (
|
||||
<ScrollAreaPrimitive.Root
|
||||
ref={ref}
|
||||
className={clsx(classNames.root, className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
ScrollAreaRoot.displayName = ScrollAreaPrimitive.Root.displayName;
|
||||
|
||||
const ScrollAreaViewport = forwardRef<
|
||||
React.ElementRef<typeof ScrollAreaPrimitive.Viewport>,
|
||||
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Viewport>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<ScrollAreaPrimitive.Viewport
|
||||
ref={ref}
|
||||
className={clsx('canon-ScrollAreaViewport', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
>(({ className, ...props }, ref) => {
|
||||
const { classNames } = useStyles('ScrollArea');
|
||||
|
||||
return (
|
||||
<ScrollAreaPrimitive.Viewport
|
||||
ref={ref}
|
||||
className={clsx(classNames.viewport, className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
ScrollAreaViewport.displayName = ScrollAreaPrimitive.Viewport.displayName;
|
||||
|
||||
const ScrollAreaScrollbar = forwardRef<
|
||||
React.ElementRef<typeof ScrollAreaPrimitive.Scrollbar>,
|
||||
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Scrollbar>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<ScrollAreaPrimitive.Scrollbar
|
||||
ref={ref}
|
||||
className={clsx('canon-ScrollAreaScrollbar', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
>(({ className, ...props }, ref) => {
|
||||
const { classNames } = useStyles('ScrollArea');
|
||||
|
||||
return (
|
||||
<ScrollAreaPrimitive.Scrollbar
|
||||
ref={ref}
|
||||
className={clsx(classNames.scrollbar, className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
ScrollAreaScrollbar.displayName = ScrollAreaPrimitive.Scrollbar.displayName;
|
||||
|
||||
const ScrollAreaThumb = forwardRef<
|
||||
React.ElementRef<typeof ScrollAreaPrimitive.Thumb>,
|
||||
React.ComponentPropsWithoutRef<typeof ScrollAreaPrimitive.Thumb>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<ScrollAreaPrimitive.Thumb
|
||||
ref={ref}
|
||||
className={clsx('canon-ScrollAreaThumb', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
>(({ className, ...props }, ref) => {
|
||||
const { classNames } = useStyles('ScrollArea');
|
||||
|
||||
return (
|
||||
<ScrollAreaPrimitive.Thumb
|
||||
ref={ref}
|
||||
className={clsx(classNames.thumb, className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
ScrollAreaThumb.displayName = ScrollAreaPrimitive.Thumb.displayName;
|
||||
|
||||
/** @public */
|
||||
|
||||
@@ -21,6 +21,7 @@ import clsx from 'clsx';
|
||||
import './Select.styles.css';
|
||||
import { SelectProps } from './types';
|
||||
import { useResponsiveValue } from '../../hooks/useResponsiveValue';
|
||||
import { useStyles } from '../../hooks/useStyles';
|
||||
|
||||
/** @public */
|
||||
export const Select = forwardRef<HTMLDivElement, SelectProps>((props, ref) => {
|
||||
@@ -37,8 +38,7 @@ export const Select = forwardRef<HTMLDivElement, SelectProps>((props, ref) => {
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
// Get the responsive value for the variant
|
||||
const responsiveSize = useResponsiveValue(size);
|
||||
const { classNames, dataAttributes } = useStyles('Select');
|
||||
|
||||
// Generate unique IDs for accessibility
|
||||
const selectId = useId();
|
||||
@@ -58,7 +58,7 @@ export const Select = forwardRef<HTMLDivElement, SelectProps>((props, ref) => {
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={clsx('canon-Select', className)} style={style} ref={ref}>
|
||||
<div className={clsx(classNames.root, className)} style={style} ref={ref}>
|
||||
{label && (
|
||||
<label
|
||||
className="canon-SelectLabel"
|
||||
@@ -68,7 +68,7 @@ export const Select = forwardRef<HTMLDivElement, SelectProps>((props, ref) => {
|
||||
>
|
||||
{label}
|
||||
{required && (
|
||||
<span aria-hidden="true" className="canon-SelectRequired">
|
||||
<span aria-hidden="true" className={classNames.required}>
|
||||
(Required)
|
||||
</span>
|
||||
)}
|
||||
@@ -78,33 +78,35 @@ export const Select = forwardRef<HTMLDivElement, SelectProps>((props, ref) => {
|
||||
<SelectPrimitive.Trigger
|
||||
ref={triggerRef}
|
||||
id={selectId}
|
||||
className="canon-SelectTrigger"
|
||||
data-size={responsiveSize}
|
||||
className={classNames.trigger}
|
||||
data-size={dataAttributes.size}
|
||||
data-invalid={error}
|
||||
>
|
||||
<SelectPrimitive.Value
|
||||
className="canon-SelectValue"
|
||||
className={classNames.value}
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
<SelectPrimitive.Icon className="canon-SelectIcon">
|
||||
<SelectPrimitive.Icon className={classNames.icon}>
|
||||
<Icon name="chevron-down" />
|
||||
</SelectPrimitive.Icon>
|
||||
</SelectPrimitive.Trigger>
|
||||
<SelectPrimitive.Portal>
|
||||
<SelectPrimitive.Backdrop />
|
||||
<SelectPrimitive.Positioner>
|
||||
<SelectPrimitive.Popup className="canon-SelectPopup">
|
||||
<SelectPrimitive.Popup className={classNames.popup}>
|
||||
{options?.map(option => (
|
||||
<SelectPrimitive.Item
|
||||
key={option.value}
|
||||
value={option.value}
|
||||
disabled={option.disabled}
|
||||
className="canon-SelectItem"
|
||||
className={classNames.item}
|
||||
>
|
||||
<SelectPrimitive.ItemIndicator className="canon-SelectItemIndicator">
|
||||
<SelectPrimitive.ItemIndicator
|
||||
className={classNames.itemIndicator}
|
||||
>
|
||||
<Icon name="check" />
|
||||
</SelectPrimitive.ItemIndicator>
|
||||
<SelectPrimitive.ItemText className="canon-SelectItemText">
|
||||
<SelectPrimitive.ItemText className={classNames.itemText}>
|
||||
{option.label}
|
||||
</SelectPrimitive.ItemText>
|
||||
</SelectPrimitive.Item>
|
||||
@@ -114,12 +116,12 @@ export const Select = forwardRef<HTMLDivElement, SelectProps>((props, ref) => {
|
||||
</SelectPrimitive.Portal>
|
||||
</SelectPrimitive.Root>
|
||||
{description && (
|
||||
<p className="canon-SelectDescription" id={descriptionId}>
|
||||
<p className={classNames.description} id={descriptionId}>
|
||||
{description}
|
||||
</p>
|
||||
)}
|
||||
{error && (
|
||||
<p className="canon-SelectError" id={errorId} role="alert">
|
||||
<p className={classNames.error} id={errorId} role="alert">
|
||||
{error}
|
||||
</p>
|
||||
)}
|
||||
|
||||
@@ -17,13 +17,16 @@
|
||||
import { forwardRef } from 'react';
|
||||
import { Switch as AriaSwitch } from 'react-aria-components';
|
||||
import type { SwitchProps } from './types';
|
||||
import { useStyles } from '../../hooks/useStyles';
|
||||
|
||||
/** @public */
|
||||
export const Switch = forwardRef<HTMLLabelElement, SwitchProps>(
|
||||
({ label, ...props }, ref) => {
|
||||
const { classNames } = useStyles('Switch');
|
||||
|
||||
return (
|
||||
<AriaSwitch className="canon-Switch" ref={ref} {...props}>
|
||||
<div className="canon-SwitchIndicator" />
|
||||
<AriaSwitch className={classNames.root} ref={ref} {...props}>
|
||||
<div className={classNames.indicator} />
|
||||
{label}
|
||||
</AriaSwitch>
|
||||
);
|
||||
|
||||
@@ -20,63 +20,88 @@ import { TableCell } from './TableCell/TableCell';
|
||||
import { TableCellText } from './TableCellText/TableCellText';
|
||||
import { TableCellLink } from './TableCellLink/TableCellLink';
|
||||
import { TableCellProfile } from './TableCellProfile/TableCellProfile';
|
||||
import { useStyles } from '../../hooks/useStyles';
|
||||
|
||||
const TableRoot = forwardRef<
|
||||
HTMLTableElement,
|
||||
React.HTMLAttributes<HTMLTableElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<table ref={ref} className={clsx('canon-TableRoot', className)} {...props} />
|
||||
));
|
||||
>(({ className, ...props }, ref) => {
|
||||
const { classNames } = useStyles('Table');
|
||||
|
||||
return (
|
||||
<table ref={ref} className={clsx(classNames.root, className)} {...props} />
|
||||
);
|
||||
});
|
||||
TableRoot.displayName = 'TableRoot';
|
||||
|
||||
const TableHeader = forwardRef<
|
||||
HTMLTableSectionElement,
|
||||
React.HTMLAttributes<HTMLTableSectionElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<thead
|
||||
ref={ref}
|
||||
className={clsx('canon-TableHeader', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
>(({ className, ...props }, ref) => {
|
||||
const { classNames } = useStyles('Table');
|
||||
|
||||
return (
|
||||
<thead
|
||||
ref={ref}
|
||||
className={clsx(classNames.header, className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
TableHeader.displayName = 'TableHeader';
|
||||
|
||||
const TableBody = forwardRef<
|
||||
HTMLTableSectionElement,
|
||||
React.HTMLAttributes<HTMLTableSectionElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<tbody ref={ref} className={clsx('canon-TableBody', className)} {...props} />
|
||||
));
|
||||
>(({ className, ...props }, ref) => {
|
||||
const { classNames } = useStyles('Table');
|
||||
|
||||
return (
|
||||
<tbody ref={ref} className={clsx(classNames.body, className)} {...props} />
|
||||
);
|
||||
});
|
||||
TableBody.displayName = 'TableBody';
|
||||
|
||||
const TableRow = forwardRef<
|
||||
HTMLTableRowElement,
|
||||
React.HTMLAttributes<HTMLTableRowElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<tr ref={ref} className={clsx('canon-TableRow', className)} {...props}>
|
||||
{props.children}
|
||||
</tr>
|
||||
));
|
||||
>(({ className, ...props }, ref) => {
|
||||
const { classNames } = useStyles('Table');
|
||||
|
||||
return (
|
||||
<tr ref={ref} className={clsx(classNames.row, className)} {...props}>
|
||||
{props.children}
|
||||
</tr>
|
||||
);
|
||||
});
|
||||
TableRow.displayName = 'TableRow';
|
||||
|
||||
const TableHead = forwardRef<
|
||||
HTMLTableCellElement,
|
||||
React.ThHTMLAttributes<HTMLTableCellElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<th ref={ref} className={clsx('canon-TableHead', className)} {...props} />
|
||||
));
|
||||
>(({ className, ...props }, ref) => {
|
||||
const { classNames } = useStyles('Table');
|
||||
|
||||
return (
|
||||
<th ref={ref} className={clsx(classNames.head, className)} {...props} />
|
||||
);
|
||||
});
|
||||
TableHead.displayName = 'TableHead';
|
||||
|
||||
const TableCaption = forwardRef<
|
||||
HTMLTableCaptionElement,
|
||||
React.HTMLAttributes<HTMLTableCaptionElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<caption
|
||||
ref={ref}
|
||||
className={clsx('canon-TableCaption', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
>(({ className, ...props }, ref) => {
|
||||
const { classNames } = useStyles('Table');
|
||||
|
||||
return (
|
||||
<caption
|
||||
ref={ref}
|
||||
className={clsx(classNames.caption, className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
TableCaption.displayName = 'TableCaption';
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,14 +16,19 @@
|
||||
|
||||
import { forwardRef } from 'react';
|
||||
import clsx from 'clsx';
|
||||
import { useStyles } from '../../../hooks/useStyles';
|
||||
|
||||
/** @public */
|
||||
const TableCell = forwardRef<
|
||||
HTMLTableCellElement,
|
||||
React.TdHTMLAttributes<HTMLTableCellElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<td ref={ref} className={clsx('canon-TableCell', className)} {...props} />
|
||||
));
|
||||
>(({ className, ...props }, ref) => {
|
||||
const { classNames } = useStyles('Table');
|
||||
|
||||
return (
|
||||
<td ref={ref} className={clsx(classNames.cell, className)} {...props} />
|
||||
);
|
||||
});
|
||||
TableCell.displayName = 'TableCell';
|
||||
|
||||
export { TableCell };
|
||||
|
||||
@@ -19,27 +19,32 @@ import clsx from 'clsx';
|
||||
import { TableCellLinkProps } from './types';
|
||||
import { Text } from '../../Text/Text';
|
||||
import { Link } from '../../Link/Link';
|
||||
import { useStyles } from '../../../hooks/useStyles';
|
||||
|
||||
/** @public */
|
||||
const TableCellLink = forwardRef<HTMLDivElement, TableCellLinkProps>(
|
||||
({ className, title, description, href, render, ...props }, ref) => (
|
||||
<div
|
||||
ref={ref}
|
||||
className={clsx('canon-TableCellLink', className)}
|
||||
{...props}
|
||||
>
|
||||
{title && (
|
||||
<Link href={href} render={render}>
|
||||
{title}
|
||||
</Link>
|
||||
)}
|
||||
{description && (
|
||||
<Text variant="body" color="secondary">
|
||||
{description}
|
||||
</Text>
|
||||
)}
|
||||
</div>
|
||||
),
|
||||
({ className, title, description, href, render, ...props }, ref) => {
|
||||
const { classNames } = useStyles('Table');
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={clsx(classNames.cellLink, className)}
|
||||
{...props}
|
||||
>
|
||||
{title && (
|
||||
<Link href={href} render={render}>
|
||||
{title}
|
||||
</Link>
|
||||
)}
|
||||
{description && (
|
||||
<Text variant="body" color="secondary">
|
||||
{description}
|
||||
</Text>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
);
|
||||
TableCellLink.displayName = 'TableCellLink';
|
||||
|
||||
|
||||
@@ -20,40 +20,45 @@ import { TableCellProfileProps } from './types';
|
||||
import { Text } from '../../Text/Text';
|
||||
import { Link } from '../../Link/Link';
|
||||
import { Avatar } from '@base-ui-components/react/avatar';
|
||||
import { useStyles } from '../../../hooks/useStyles';
|
||||
|
||||
/** @public */
|
||||
const TableCellProfile = forwardRef<HTMLDivElement, TableCellProfileProps>(
|
||||
({ className, src, name, to, withImage = true, ...rest }, ref) => (
|
||||
<div
|
||||
ref={ref}
|
||||
className={clsx('canon-TableCellProfile', className)}
|
||||
{...rest}
|
||||
>
|
||||
{withImage && (
|
||||
<Avatar.Root className="canon-TableCellProfileAvatar">
|
||||
<Avatar.Image
|
||||
src={src}
|
||||
width="20"
|
||||
height="20"
|
||||
className="canon-TableCellProfileAvatarImage"
|
||||
/>
|
||||
<Avatar.Fallback className="canon-TableCellProfileAvatarFallback">
|
||||
{(name || '')
|
||||
.split(' ')
|
||||
.map(word => word[0])
|
||||
.join('')
|
||||
.toLocaleUpperCase('en-US')
|
||||
.slice(0, 1)}
|
||||
</Avatar.Fallback>
|
||||
</Avatar.Root>
|
||||
)}
|
||||
{name && to ? (
|
||||
<Link to={to}>{name}</Link>
|
||||
) : (
|
||||
<Text variant="body">{name}</Text>
|
||||
)}
|
||||
</div>
|
||||
),
|
||||
({ className, src, name, to, withImage = true, ...rest }, ref) => {
|
||||
const { classNames } = useStyles('Table');
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={clsx(classNames.cellProfile, className)}
|
||||
{...rest}
|
||||
>
|
||||
{withImage && (
|
||||
<Avatar.Root className={classNames.cellProfileAvatar}>
|
||||
<Avatar.Image
|
||||
src={src}
|
||||
width="20"
|
||||
height="20"
|
||||
className={classNames.cellProfileAvatarImage}
|
||||
/>
|
||||
<Avatar.Fallback className={classNames.cellProfileAvatarFallback}>
|
||||
{(name || '')
|
||||
.split(' ')
|
||||
.map(word => word[0])
|
||||
.join('')
|
||||
.toLocaleUpperCase('en-US')
|
||||
.slice(0, 1)}
|
||||
</Avatar.Fallback>
|
||||
</Avatar.Root>
|
||||
)}
|
||||
{name && to ? (
|
||||
<Link to={to}>{name}</Link>
|
||||
) : (
|
||||
<Text variant="body">{name}</Text>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
);
|
||||
TableCellProfile.displayName = 'TableCellProfile';
|
||||
|
||||
|
||||
@@ -18,23 +18,28 @@ import { forwardRef } from 'react';
|
||||
import clsx from 'clsx';
|
||||
import { TableCellTextProps } from './types';
|
||||
import { Text } from '../../Text/Text';
|
||||
import { useStyles } from '../../../hooks/useStyles';
|
||||
|
||||
/** @public */
|
||||
const TableCellText = forwardRef<HTMLDivElement, TableCellTextProps>(
|
||||
({ className, title, description, ...props }, ref) => (
|
||||
<div
|
||||
ref={ref}
|
||||
className={clsx('canon-TableCellText', className)}
|
||||
{...props}
|
||||
>
|
||||
{title && <Text variant="body">{title}</Text>}
|
||||
{description && (
|
||||
<Text variant="body" color="secondary">
|
||||
{description}
|
||||
</Text>
|
||||
)}
|
||||
</div>
|
||||
),
|
||||
({ className, title, description, ...props }, ref) => {
|
||||
const { classNames } = useStyles('Table');
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={clsx(classNames.cellText, className)}
|
||||
{...props}
|
||||
>
|
||||
{title && <Text variant="body">{title}</Text>}
|
||||
{description && (
|
||||
<Text variant="body" color="secondary">
|
||||
{description}
|
||||
</Text>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
);
|
||||
TableCellText.displayName = 'TableCellText';
|
||||
|
||||
|
||||
@@ -18,56 +18,73 @@ import { forwardRef } from 'react';
|
||||
import { Tabs as TabsPrimitive } from '@base-ui-components/react/tabs';
|
||||
import type { TabsRootWithoutOrientation } from './types';
|
||||
import clsx from 'clsx';
|
||||
import { useStyles } from '../../hooks/useStyles';
|
||||
|
||||
const TabsRoot = forwardRef<
|
||||
React.ElementRef<typeof TabsPrimitive.Root>,
|
||||
TabsRootWithoutOrientation
|
||||
>(({ className, ...props }, ref) => (
|
||||
<TabsPrimitive.Root
|
||||
ref={ref}
|
||||
className={clsx('canon-TabsRoot', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
>(({ className, ...props }, ref) => {
|
||||
const { classNames } = useStyles('Tabs');
|
||||
|
||||
return (
|
||||
<TabsPrimitive.Root
|
||||
ref={ref}
|
||||
className={clsx(classNames.root, className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
TabsRoot.displayName = TabsPrimitive.Root.displayName;
|
||||
|
||||
const TabsList = forwardRef<
|
||||
React.ElementRef<typeof TabsPrimitive.List>,
|
||||
React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
|
||||
>(({ className, children, ...props }, ref) => (
|
||||
<TabsPrimitive.List
|
||||
ref={ref}
|
||||
className={clsx('canon-TabsList', className)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<TabsPrimitive.Indicator className="canon-TabsIndicator" />
|
||||
</TabsPrimitive.List>
|
||||
));
|
||||
>(({ className, children, ...props }, ref) => {
|
||||
const { classNames } = useStyles('Tabs');
|
||||
|
||||
return (
|
||||
<TabsPrimitive.List
|
||||
ref={ref}
|
||||
className={clsx(classNames.list, className)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<TabsPrimitive.Indicator className={classNames.indicator} />
|
||||
</TabsPrimitive.List>
|
||||
);
|
||||
});
|
||||
TabsList.displayName = TabsPrimitive.List.displayName;
|
||||
|
||||
const TabsTab = forwardRef<
|
||||
React.ElementRef<typeof TabsPrimitive.Tab>,
|
||||
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Tab>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<TabsPrimitive.Tab
|
||||
ref={ref}
|
||||
className={clsx('canon-TabsTab', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
>(({ className, ...props }, ref) => {
|
||||
const { classNames } = useStyles('Tabs');
|
||||
|
||||
return (
|
||||
<TabsPrimitive.Tab
|
||||
ref={ref}
|
||||
className={clsx(classNames.tab, className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
TabsTab.displayName = TabsPrimitive.Tab.displayName;
|
||||
|
||||
const TabsPanel = forwardRef<
|
||||
React.ElementRef<typeof TabsPrimitive.Panel>,
|
||||
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Panel>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<TabsPrimitive.Panel
|
||||
ref={ref}
|
||||
className={clsx('canon-TabsPanel', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
>(({ className, ...props }, ref) => {
|
||||
const { classNames } = useStyles('Tabs');
|
||||
|
||||
return (
|
||||
<TabsPrimitive.Panel
|
||||
ref={ref}
|
||||
className={clsx(classNames.panel, className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
TabsPanel.displayName = TabsPrimitive.Panel.displayName;
|
||||
|
||||
/** @public */
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
*/
|
||||
|
||||
import { forwardRef } from 'react';
|
||||
import { useResponsiveValue } from '../../hooks/useResponsiveValue';
|
||||
import clsx from 'clsx';
|
||||
import type { ElementType } from 'react';
|
||||
import type { TextProps } from './types';
|
||||
import { useStyles } from '../../hooks/useStyles';
|
||||
|
||||
function TextComponent<T extends ElementType = 'p'>(
|
||||
{
|
||||
@@ -35,19 +35,18 @@ function TextComponent<T extends ElementType = 'p'>(
|
||||
) {
|
||||
const Component = as || 'p';
|
||||
|
||||
// Get the responsive values for the variant and weight
|
||||
const responsiveVariant = useResponsiveValue(variant);
|
||||
const responsiveWeight = useResponsiveValue(weight);
|
||||
const responsiveColor = useResponsiveValue(color);
|
||||
const { classNames, dataAttributes } = useStyles('Text', {
|
||||
variant,
|
||||
weight,
|
||||
color,
|
||||
truncate,
|
||||
});
|
||||
|
||||
return (
|
||||
<Component
|
||||
ref={ref}
|
||||
className={clsx('canon-Text', className)}
|
||||
data-variant={responsiveVariant}
|
||||
data-weight={responsiveWeight}
|
||||
data-color={responsiveColor}
|
||||
data-truncate={truncate}
|
||||
className={clsx(classNames.root, className)}
|
||||
{...dataAttributes}
|
||||
style={style}
|
||||
{...restProps}
|
||||
/>
|
||||
|
||||
@@ -16,12 +16,12 @@
|
||||
|
||||
import { forwardRef, useEffect } from 'react';
|
||||
import { Input, TextField as AriaTextField } from 'react-aria-components';
|
||||
import { useResponsiveValue } from '../../hooks/useResponsiveValue';
|
||||
import clsx from 'clsx';
|
||||
import { FieldLabel } from '../FieldLabel';
|
||||
import { FieldError } from '../FieldError';
|
||||
|
||||
import type { TextFieldProps } from './types';
|
||||
import { useStyles } from '../../hooks/useStyles';
|
||||
|
||||
/** @public */
|
||||
export const TextField = forwardRef<HTMLDivElement, TextFieldProps>(
|
||||
@@ -49,7 +49,9 @@ export const TextField = forwardRef<HTMLDivElement, TextFieldProps>(
|
||||
}, [label, ariaLabel, ariaLabelledBy]);
|
||||
|
||||
// Get the responsive value for the variant
|
||||
const responsiveSize = useResponsiveValue(size);
|
||||
const { classNames, dataAttributes } = useStyles('TextField', {
|
||||
size,
|
||||
});
|
||||
|
||||
// If a secondary label is provided, use it. Otherwise, use 'Required' if the field is required.
|
||||
const secondaryLabelText =
|
||||
@@ -57,8 +59,8 @@ export const TextField = forwardRef<HTMLDivElement, TextFieldProps>(
|
||||
|
||||
return (
|
||||
<AriaTextField
|
||||
className={clsx('canon-TextField', className)}
|
||||
data-size={responsiveSize}
|
||||
className={clsx(classNames.root, className)}
|
||||
{...dataAttributes}
|
||||
aria-label={ariaLabel}
|
||||
aria-labelledby={ariaLabelledBy}
|
||||
{...rest}
|
||||
@@ -69,18 +71,21 @@ export const TextField = forwardRef<HTMLDivElement, TextFieldProps>(
|
||||
secondaryLabel={secondaryLabelText}
|
||||
description={description}
|
||||
/>
|
||||
<div className="canon-TextFieldInputWrapper" data-size={responsiveSize}>
|
||||
<div
|
||||
className={classNames.inputWrapper}
|
||||
data-size={dataAttributes.size}
|
||||
>
|
||||
{icon && (
|
||||
<div
|
||||
className="canon-TextFieldIcon"
|
||||
data-size={responsiveSize}
|
||||
className={classNames.icon}
|
||||
data-size={dataAttributes.size}
|
||||
aria-hidden="true"
|
||||
>
|
||||
{icon}
|
||||
</div>
|
||||
)}
|
||||
<Input
|
||||
className="canon-TextFieldInput"
|
||||
className={classNames.input}
|
||||
{...(icon && { 'data-icon': true })}
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
|
||||
@@ -17,68 +17,85 @@
|
||||
import { forwardRef } from 'react';
|
||||
import { Tooltip as TooltipPrimitive } from '@base-ui-components/react/tooltip';
|
||||
import clsx from 'clsx';
|
||||
import { useStyles } from '../../hooks/useStyles';
|
||||
|
||||
const TooltipTrigger = forwardRef<
|
||||
React.ElementRef<typeof TooltipPrimitive.Trigger>,
|
||||
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Trigger>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<TooltipPrimitive.Trigger
|
||||
ref={ref}
|
||||
className={clsx('canon-TooltipTrigger', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
>(({ className, ...props }, ref) => {
|
||||
const { classNames } = useStyles('Tooltip');
|
||||
|
||||
return (
|
||||
<TooltipPrimitive.Trigger
|
||||
ref={ref}
|
||||
className={clsx(classNames.trigger, className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
TooltipTrigger.displayName = TooltipPrimitive.Trigger.displayName;
|
||||
|
||||
const TooltipPositioner = forwardRef<
|
||||
React.ElementRef<typeof TooltipPrimitive.Positioner>,
|
||||
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Positioner>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<TooltipPrimitive.Positioner
|
||||
ref={ref}
|
||||
className={clsx('canon-TooltipPositioner', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
>(({ className, ...props }, ref) => {
|
||||
const { classNames } = useStyles('Tooltip');
|
||||
|
||||
return (
|
||||
<TooltipPrimitive.Positioner
|
||||
ref={ref}
|
||||
className={clsx(classNames.positioner, className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
TooltipPositioner.displayName = TooltipPrimitive.Positioner.displayName;
|
||||
|
||||
const TooltipPopup = forwardRef<
|
||||
React.ElementRef<typeof TooltipPrimitive.Popup>,
|
||||
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Popup>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<TooltipPrimitive.Popup
|
||||
ref={ref}
|
||||
className={clsx('canon-TooltipPopup', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
>(({ className, ...props }, ref) => {
|
||||
const { classNames } = useStyles('Tooltip');
|
||||
|
||||
return (
|
||||
<TooltipPrimitive.Popup
|
||||
ref={ref}
|
||||
className={clsx(classNames.popup, className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
});
|
||||
TooltipPopup.displayName = TooltipPrimitive.Popup.displayName;
|
||||
|
||||
const TooltipArrow = forwardRef<
|
||||
React.ElementRef<typeof TooltipPrimitive.Arrow>,
|
||||
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Arrow>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<TooltipPrimitive.Arrow
|
||||
ref={ref}
|
||||
className={clsx('canon-TooltipArrow', className)}
|
||||
{...props}
|
||||
>
|
||||
<svg width="20" height="10" viewBox="0 0 20 10" fill="none">
|
||||
<path
|
||||
d="M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z"
|
||||
className="canon-TooltipArrow-fill"
|
||||
/>
|
||||
<path
|
||||
d="M8.99542 1.85876C9.75604 1.17425 10.9106 1.17422 11.6713 1.85878L16.5281 6.22989C17.0789 6.72568 17.7938 7.00001 18.5349 7.00001L15.89 7L11.0023 2.60207C10.622 2.2598 10.0447 2.2598 9.66436 2.60207L4.77734 7L2.13171 7.00001C2.87284 7.00001 3.58774 6.72568 4.13861 6.22989L8.99542 1.85876Z"
|
||||
className="canon-TooltipArrow-outer-stroke"
|
||||
/>
|
||||
<path
|
||||
d="M10.3333 3.34539L5.47654 7.71648C4.55842 8.54279 3.36693 9 2.13172 9H0V8H2.13172C3.11989 8 4.07308 7.63423 4.80758 6.97318L9.66437 2.60207C10.0447 2.25979 10.622 2.2598 11.0023 2.60207L15.8591 6.97318C16.5936 7.63423 17.5468 8 18.5349 8H20V9H18.5349C17.2998 9 16.1083 8.54278 15.1901 7.71648L10.3333 3.34539Z"
|
||||
className="canon-TooltipArrow-inner-stroke"
|
||||
/>
|
||||
</svg>
|
||||
</TooltipPrimitive.Arrow>
|
||||
));
|
||||
>(({ className, ...props }, ref) => {
|
||||
const { classNames } = useStyles('Tooltip');
|
||||
|
||||
return (
|
||||
<TooltipPrimitive.Arrow
|
||||
ref={ref}
|
||||
className={clsx(classNames.arrow, className)}
|
||||
{...props}
|
||||
>
|
||||
<svg width="20" height="10" viewBox="0 0 20 10" fill="none">
|
||||
<path
|
||||
d="M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z"
|
||||
className="canon-TooltipArrow-fill"
|
||||
/>
|
||||
<path
|
||||
d="M8.99542 1.85876C9.75604 1.17425 10.9106 1.17422 11.6713 1.85878L16.5281 6.22989C17.0789 6.72568 17.7938 7.00001 18.5349 7.00001L15.89 7L11.0023 2.60207C10.622 2.2598 10.0447 2.2598 9.66436 2.60207L4.77734 7L2.13171 7.00001C2.87284 7.00001 3.58774 6.72568 4.13861 6.22989L8.99542 1.85876Z"
|
||||
className="canon-TooltipArrow-outer-stroke"
|
||||
/>
|
||||
<path
|
||||
d="M10.3333 3.34539L5.47654 7.71648C4.55842 8.54279 3.36693 9 2.13172 9H0V8H2.13172C3.11989 8 4.07308 7.63423 4.80758 6.97318L9.66437 2.60207C10.0447 2.25979 10.622 2.2598 11.0023 2.60207L15.8591 6.97318C16.5936 7.63423 17.5468 8 18.5349 8H20V9H18.5349C17.2998 9 16.1083 8.54278 15.1901 7.71648L10.3333 3.34539Z"
|
||||
className="canon-TooltipArrow-inner-stroke"
|
||||
/>
|
||||
</svg>
|
||||
</TooltipPrimitive.Arrow>
|
||||
);
|
||||
});
|
||||
TooltipArrow.displayName = TooltipPrimitive.Arrow.displayName;
|
||||
|
||||
/** @public */
|
||||
|
||||
@@ -139,6 +139,13 @@ export const componentDefinitions = {
|
||||
separator: 'canon-MenuSeparator',
|
||||
},
|
||||
},
|
||||
RadioGroup: {
|
||||
classNames: {
|
||||
root: 'canon-RadioGroup',
|
||||
content: 'canon-RadioGroupContent',
|
||||
radio: 'canon-Radio',
|
||||
},
|
||||
},
|
||||
ScrollArea: {
|
||||
classNames: {
|
||||
root: 'canon-ScrollAreaRoot',
|
||||
@@ -147,117 +154,87 @@ export const componentDefinitions = {
|
||||
thumb: 'canon-ScrollAreaThumb',
|
||||
},
|
||||
},
|
||||
|
||||
// Typography Components
|
||||
Select: {
|
||||
classNames: {
|
||||
root: 'canon-Select',
|
||||
required: 'canon-SelectRequired',
|
||||
trigger: 'canon-SelectTrigger',
|
||||
value: 'canon-SelectValue',
|
||||
icon: 'canon-SelectIcon',
|
||||
popup: 'canon-SelectPopup',
|
||||
item: 'canon-SelectItem',
|
||||
itemIndicator: 'canon-SelectItemIndicator',
|
||||
itemText: 'canon-SelectItemText',
|
||||
description: 'canon-SelectDescription',
|
||||
error: 'canon-SelectError',
|
||||
},
|
||||
dataAttributes: {
|
||||
size: ['small', 'medium'] as const,
|
||||
},
|
||||
},
|
||||
Switch: {
|
||||
classNames: {
|
||||
root: 'canon-Switch',
|
||||
indicator: 'canon-SwitchIndicator',
|
||||
},
|
||||
},
|
||||
Table: {
|
||||
classNames: {
|
||||
root: 'canon-TableRoot',
|
||||
header: 'canon-TableHeader',
|
||||
body: 'canon-TableBody',
|
||||
row: 'canon-TableRow',
|
||||
head: 'canon-TableHead',
|
||||
caption: 'canon-TableCaption',
|
||||
cell: 'canon-TableCell',
|
||||
cellText: 'canon-TableCellText',
|
||||
cellLink: 'canon-TableCellLink',
|
||||
cellProfile: 'canon-TableCellProfile',
|
||||
cellProfileAvatar: 'canon-TableCellProfileAvatar',
|
||||
cellProfileAvatarImage: 'canon-TableCellProfileAvatarImage',
|
||||
cellProfileAvatarFallback: 'canon-TableCellProfileAvatarFallback',
|
||||
cellProfileName: 'canon-TableCellProfileName',
|
||||
cellProfileLink: 'canon-TableCellProfileLink',
|
||||
},
|
||||
},
|
||||
Tabs: {
|
||||
classNames: {
|
||||
root: 'canon-TabsRoot',
|
||||
list: 'canon-TabsList',
|
||||
indicator: 'canon-TabsIndicator',
|
||||
tab: 'canon-TabsTab',
|
||||
panel: 'canon-TabsPanel',
|
||||
},
|
||||
},
|
||||
Text: {
|
||||
classNames: {
|
||||
root: 'canon-Text',
|
||||
},
|
||||
dataAttributes: {
|
||||
variant: ['body', 'caption', 'label'] as const,
|
||||
weight: ['regular', 'medium', 'bold'] as const,
|
||||
color: ['primary', 'secondary', 'muted'] as const,
|
||||
variant: ['subtitle', 'body', 'caption', 'label'] as const,
|
||||
weight: ['regular', 'bold'] as const,
|
||||
color: ['primary', 'secondary', 'danger', 'warning', 'success'] as const,
|
||||
truncate: [true, false] as const,
|
||||
},
|
||||
},
|
||||
|
||||
TextField: {
|
||||
classNames: {
|
||||
root: 'canon-TextField',
|
||||
input: 'canon-TextField-input',
|
||||
label: 'canon-TextField-label',
|
||||
error: 'canon-TextField-error',
|
||||
helper: 'canon-TextField-helper',
|
||||
container: 'canon-TextField-container',
|
||||
inputWrapper: 'canon-TextFieldInputWrapper',
|
||||
icon: 'canon-TextFieldIcon',
|
||||
input: 'canon-TextFieldInput',
|
||||
},
|
||||
dataAttributes: {
|
||||
invalid: [true, false] as const,
|
||||
disabled: [true, false] as const,
|
||||
},
|
||||
},
|
||||
|
||||
Select: {
|
||||
classNames: {
|
||||
root: 'canon-Select',
|
||||
trigger: 'canon-Select-trigger',
|
||||
content: 'canon-Select-content',
|
||||
item: 'canon-Select-item',
|
||||
value: 'canon-Select-value',
|
||||
icon: 'canon-Select-icon',
|
||||
separator: 'canon-Select-separator',
|
||||
},
|
||||
dataAttributes: {
|
||||
invalid: [true, false] as const,
|
||||
disabled: [true, false] as const,
|
||||
open: [true, false] as const,
|
||||
},
|
||||
},
|
||||
|
||||
Switch: {
|
||||
classNames: {
|
||||
root: 'canon-Switch',
|
||||
thumb: 'canon-Switch-thumb',
|
||||
track: 'canon-Switch-track',
|
||||
},
|
||||
dataAttributes: {
|
||||
checked: [true, false] as const,
|
||||
disabled: [true, false] as const,
|
||||
},
|
||||
},
|
||||
|
||||
// Navigation Components
|
||||
|
||||
Tabs: {
|
||||
classNames: {
|
||||
root: 'canon-Tabs',
|
||||
list: 'canon-Tabs-list',
|
||||
tab: 'canon-Tabs-tab',
|
||||
panel: 'canon-Tabs-panel',
|
||||
trigger: 'canon-Tabs-trigger',
|
||||
},
|
||||
},
|
||||
|
||||
// Data Display Components
|
||||
Table: {
|
||||
classNames: {
|
||||
root: 'canon-Table',
|
||||
header: 'canon-Table-header',
|
||||
body: 'canon-Table-body',
|
||||
footer: 'canon-Table-footer',
|
||||
row: 'canon-Table-row',
|
||||
cell: 'canon-Table-cell',
|
||||
headerCell: 'canon-Table-headerCell',
|
||||
caption: 'canon-Table-caption',
|
||||
},
|
||||
},
|
||||
|
||||
DataTable: {
|
||||
classNames: {
|
||||
root: 'canon-DataTable',
|
||||
container: 'canon-DataTable-container',
|
||||
header: 'canon-DataTable-header',
|
||||
body: 'canon-DataTable-body',
|
||||
row: 'canon-DataTable-row',
|
||||
cell: 'canon-DataTable-cell',
|
||||
headerCell: 'canon-DataTable-headerCell',
|
||||
toolbar: 'canon-DataTable-toolbar',
|
||||
pagination: 'canon-DataTable-pagination',
|
||||
search: 'canon-DataTable-search',
|
||||
filters: 'canon-DataTable-filters',
|
||||
},
|
||||
},
|
||||
|
||||
// Feedback Components
|
||||
Tooltip: {
|
||||
classNames: {
|
||||
root: 'canon-Tooltip',
|
||||
trigger: 'canon-Tooltip-trigger',
|
||||
content: 'canon-Tooltip-content',
|
||||
arrow: 'canon-Tooltip-arrow',
|
||||
trigger: 'canon-TooltipTrigger',
|
||||
positioner: 'canon-TooltipPositioner',
|
||||
popup: 'canon-TooltipPopup',
|
||||
arrow: 'canon-TooltipArrow',
|
||||
},
|
||||
},
|
||||
|
||||
// Disclosure Components
|
||||
|
||||
// Utility Components
|
||||
} as const satisfies Record<string, ComponentDefinition>;
|
||||
|
||||
Reference in New Issue
Block a user