Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/react/src/components/AudioPlayer/AudioPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,7 @@ export const AudioPlayer = ({ ref, ...inProps }: AudioPlayerProps & RefAttribute
<ListItemIcon className="es-audio-player__list-item-icon">{iconBack}</ListItemIcon>
<ListItemText className="es-audio-player__list-item-text" primary={labelBack} />
</MenuItem>
<Divider className="es-audio-player__list-divider" />
<Divider className="es-audio-player__list-divider" component="li" role="presentation" />
{rates.map((r) => (
<MenuItem
key={r}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,12 @@ export const AutocompleteMenu = (({ ref, ...inProps }: AutocompleteMenuProps<any
if (!!groupBy && (index === 0 || group !== groupBy(options[index - 1]))) {
if (index > 0) {
groupedOptions.push(
<Divider key={`${value}-${group}-divider`} className="es-autocomplete-menu__menu-group-divider" />
<Divider
key={`${value}-${group}-divider`}
className="es-autocomplete-menu__menu-group-divider"
component="li"
role="presentation"
/>
);
}

Expand Down
4 changes: 1 addition & 3 deletions packages/react/src/components/Banner/Banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,7 @@ export const Banner = ({ ref, ...inProps }: BannerProps & RefAttributes<HTMLDivE
<div className="es-banner__wrapper">
{icon !== false && <div className="es-banner__icon">{icon || iconMapping[severity]}</div>}
<div className={clsx('es-banner__content', breakpoint && `es-banner__content--breakpoint--${breakpoint}`)}>
<div className="es-banner__message body100" color="inherit">
{children}
</div>
<div className="es-banner__message body100">{children}</div>
{actions}
</div>
{!!action && <div className="es-banner__action">{action}</div>}
Expand Down
30 changes: 28 additions & 2 deletions packages/react/src/components/ButtonBase/ButtonBase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,29 @@ import { useDefaultProps } from '../../theming';
import { OverridableComponent } from '../../types';
import { TouchRipple, useTouchRipple } from '../TouchRipple';

const FORM_ELEMENTS = ['button', 'fieldset', 'input', 'optgroup', 'option', 'select', 'textarea'];

const FLOW_CONTENT_ELEMENTS = [
'address',
'article',
'aside',
'blockquote',
'dd',
'div',
'fieldset',
'figcaption',
'figure',
'footer',
'form',
'header',
'li',
'main',
'nav',
'section',
'td',
'th',
];

/**
* The Button allows users to take actions, and make choices, with a single tap.
*/
Expand All @@ -36,6 +59,9 @@ export const ButtonBase = (({ ref, ...inProps }: ButtonBaseProps) => {
name: 'ESButtonBase',
});

const Wrapper = typeof Component === 'string' && FLOW_CONTENT_ELEMENTS.includes(Component) ? 'div' : 'span';
const isDisabledSupported = typeof Component !== 'string' || FORM_ELEMENTS.includes(Component);

const buttonRef = useRef<HTMLButtonElement | HTMLLinkElement | null>(null);
const handleRef = useForkRef(ref, buttonRef);

Expand Down Expand Up @@ -94,12 +120,12 @@ export const ButtonBase = (({ ref, ...inProps }: ButtonBaseProps) => {
disableTouchRipple && 'es-button-base--disable-touch-ripple',
pressed && 'es-button-base--pressed'
)}
disabled={disabled}
disabled={isDisabledSupported ? disabled : undefined}
type={type}
{...props}
{...bind}
>
<div className="es-button-base__wrapper">{children}</div>
<Wrapper className="es-button-base__wrapper">{children}</Wrapper>
<TouchRipple ref={touchRippleRef} />
</Component>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import { useDefaultProps } from '../../../theming';
/**
* @see `Checkbox`
*/
export const CheckboxIcon = ({ ref, ...inProps }: CheckboxIconProps & RefAttributes<HTMLDivElement>) => {
export const CheckboxIcon = ({ ref, ...inProps }: CheckboxIconProps & RefAttributes<HTMLSpanElement>) => {
const { className, ...props } = useDefaultProps({ props: inProps, name: 'ESCheckboxIcon' });

return <div ref={ref} className={clsx(className, 'es-checkbox-icon')} {...props} />;
return <span ref={ref} className={clsx(className, 'es-checkbox-icon')} {...props} />;
};
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const DialogClose = ({ ref, ...inProps }: DialogCloseProps & RefAttribute
<div ref={ref} className={clsx('es-dialog-close', className)} style={style}>
<Button aria-label={label} className="es-dialog-close__button" color="white" onClick={onClick}>
{icon}
<div className="es-dialog-close__escape-key caption">{labelEscapeKey}</div>
<span className="es-dialog-close__escape-key caption">{labelEscapeKey}</span>
</Button>
</div>
);
Expand Down
9 changes: 6 additions & 3 deletions packages/react/src/components/Divider/Divider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ import { useDefaultProps } from '../../theming';
/**
* The Divider is a thin line that groups content in lists and layouts.
*/
export const Divider = ({ ref, ...inProps }: DividerProps & RefAttributes<HTMLDivElement>) => {
export const Divider = ({ ref, ...inProps }: DividerProps & RefAttributes<HTMLElement>) => {
const {
component: Component = 'div',
className,
style,
children,
Expand All @@ -21,13 +22,14 @@ export const Divider = ({ ref, ...inProps }: DividerProps & RefAttributes<HTMLDi
orientation = 'horizontal',
textAlign = 'center',
flexItem,
role,
} = useDefaultProps({
props: inProps,
name: 'ESDivider',
});

return (
<div
<Component
ref={ref}
className={clsx(
className,
Expand All @@ -37,6 +39,7 @@ export const Divider = ({ ref, ...inProps }: DividerProps & RefAttributes<HTMLDi
!!children && `es-divider--with-children`,
!!flexItem && `es-divider--flex-item`
)}
role={role}
style={
{
'--es-divider-color': color,
Expand All @@ -46,7 +49,7 @@ export const Divider = ({ ref, ...inProps }: DividerProps & RefAttributes<HTMLDi
}
>
{children ? <span className="es-divider__wrapper caption">{children}</span> : null}
</div>
</Component>
);
};

Expand Down
10 changes: 9 additions & 1 deletion packages/react/src/components/Divider/Divider.types.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import { CSSProperties, ReactNode } from 'react';
import { CSSProperties, ElementType, ReactNode } from 'react';

export interface DividerProps {
children?: ReactNode;

/**
* The component used for the root node.
*/
component?: ElementType;

/** The aria role of the root element. */
role?: string;

/** Class applied to the root element. */
className?: string;
/** Style applied to the root element. */
Expand Down
16 changes: 8 additions & 8 deletions packages/react/src/components/Dropzone/Dropzone.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,20 +142,20 @@ export const Dropzone = (inProps: DropzoneProps): React.JSX.Element => {
onDragOver={onDragOver}
onDrop={onDropzoneDrop}
>
<div className="es-dropzone__heading">
{!!icon && !(isDragOverDocument && !!dragHeading) && <div className="es-dropzone__icon">{icon}</div>}
<span className="es-dropzone__heading">
{!!icon && !(isDragOverDocument && !!dragHeading) && <span className="es-dropzone__icon">{icon}</span>}

{isDragOverDocument && !!dragHeading ? (
<div className="es-dropzone__heading-text body200">{dragHeading}</div>
<span className="es-dropzone__heading-text body200">{dragHeading}</span>
) : (
!!heading && <div className="es-dropzone__heading-text body100">{heading}</div>
!!heading && <span className="es-dropzone__heading-text body100">{heading}</span>
)}
</div>
</span>

{isDragOverDocument && !!dragSubheading ? (
<div className="es-dropzone__subheading caption">{dragSubheading}</div>
<span className="es-dropzone__subheading caption">{dragSubheading}</span>
) : (
!!subheading && <div className="es-dropzone__subheading caption">{subheading}</div>
!!subheading && <span className="es-dropzone__subheading caption">{subheading}</span>
)}
</ButtonBase>

Expand All @@ -166,7 +166,7 @@ export const Dropzone = (inProps: DropzoneProps): React.JSX.Element => {
)}
<input
ref={inputRef}
accept={accept}
accept={accept === '*' ? undefined : accept}
className="es-dropzone__input"
multiple={multiple}
type="file"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const FormControlLabel = ({ ref, ...inProps }: FormControlLabelProps & Re
slotProps = {},
} = useDefaultProps({ props: inProps, name: 'ESFormControlLabel' });

const LabelComponent = slots.typography ?? 'div';
const LabelComponent = slots.typography ?? 'span';

const labelProps = {
...slotProps.typography,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export interface FormControlLabelProps {
* @default {}
*/
slotProps?: {
typography?: Partial<HTMLAttributes<HTMLDivElement>>;
typography?: Partial<HTMLAttributes<HTMLSpanElement>>;
};
/**
* The components used for each slot inside.
Expand Down
12 changes: 9 additions & 3 deletions packages/react/src/components/MenuGroup/MenuGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { useDefaultProps } from '../../theming';
* A heading that labels a group of items inside a dropdown menu. It can stick to the top of the menu while the list
* scrolls.
*/
export const MenuGroup = ({ ref, ...inProps }: MenuGroupProps & RefAttributes<HTMLDivElement>) => {
export const MenuGroup = ({ ref, ...inProps }: MenuGroupProps & RefAttributes<HTMLLIElement>) => {
const {
children,

Expand All @@ -27,7 +27,7 @@ export const MenuGroup = ({ ref, ...inProps }: MenuGroupProps & RefAttributes<HT
});

return (
<div
<li
ref={ref}
className={clsx(
className,
Expand All @@ -36,9 +36,15 @@ export const MenuGroup = ({ ref, ...inProps }: MenuGroupProps & RefAttributes<HT
sticky && 'es-menu-group--sticky',
'caption'
)}
role="presentation"
{...props}
>
{children}
</div>
</li>
);
};

/**
* The group is a heading, not an item, so `MenuList` must not make it focusable.
*/
MenuGroup.esSkipListHighlight = true;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import { Fragment, memo, RefAttributes, useState } from 'react';
import { memo, RefAttributes, useState } from 'react';

import { PaginationPagesProps } from './PaginationPages.types';

Expand Down Expand Up @@ -111,7 +111,7 @@ export const PaginationPages = memo(function PaginationPages({
} = slotProps?.[item.type as keyof typeof slotProps]?.(item) || {};

return (
<Fragment key={`${item.type}${item.page}`}>
<li key={`${item.type}${item.page}`} className="es-pagination-pages__item">
{item.type === 'previous' || item.type === 'next' ? (
<Button
aria-label={`${item.type === 'next' ? labelNextPage : labelPrevPage}`}
Expand Down Expand Up @@ -160,7 +160,7 @@ export const PaginationPages = memo(function PaginationPages({
</ButtonBase>
</Tooltip>
)}
</Fragment>
</li>
);
})}
</ul>
Expand Down
8 changes: 4 additions & 4 deletions packages/react/src/components/Radio/RadioIcon/RadioIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ import { useDefaultProps } from '../../../theming';
/**
* @see `Radio`
*/
export const RadioIcon = ({ ref, ...inProps }: RadioIconProps & RefAttributes<HTMLDivElement>) => {
export const RadioIcon = ({ ref, ...inProps }: RadioIconProps & RefAttributes<HTMLSpanElement>) => {
const { className, style } = useDefaultProps({ props: inProps, name: 'ESRadioIcon' });

return (
<div ref={ref} className={clsx('es-radio-icon', className)} style={style}>
<div className="es-radio-icon__circle" />
</div>
<span ref={ref} className={clsx('es-radio-icon', className)} style={style}>
<span className="es-radio-icon__circle" />
</span>
);
};
6 changes: 3 additions & 3 deletions packages/react/src/components/SFS/SFSFilters/SFSFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,14 @@ export const SFSFilters = memo(function SFSFilters({
};

return (
<div ref={ref} className={clsx(className, 'es-sfs-filters')} color="tertiary" style={style}>
<div ref={ref} className={clsx(className, 'es-sfs-filters')} style={style}>
{button ? (
button({ open: isOpen, setOpen })
) : (
<SFSButton active={!!count} className="es-sfs-filters__button" onClick={onOpen}>
<div className="body100">{labelButton}</div>
<span className="body100">{labelButton}</span>
{iconFilters}
{!!count && <div className="es-sfs-button-badge es-sfs-filters__button-badge mini200">{count}</div>}
{!!count && <span className="es-sfs-button-badge es-sfs-filters__button-badge mini200">{count}</span>}
</SFSButton>
)}
<Drawer anchor="right" className="es-sfs-filters__drawer" open={isOpen} onClose={onClose}>
Expand Down
10 changes: 5 additions & 5 deletions packages/react/src/components/SFS/SFSSorting/SFSSorting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,17 @@ export const SFSSorting = memo(function SFSSorting({
return (
<div ref={ref} className={clsx('es-sfs-sorting', className)} style={style}>
<SFSButton active={!!values[0]} className="es-sfs-sorting__button" onClick={onMenuOpen}>
<div className="body100">
<span className="body100">
{values.length === 1 ? options.find((o) => o.value === values[0].value)?.label : labelButton}
</div>
</span>
{iconSort}
{values.length === 1 && (
<div className="es-sfs-button-badge es-sfs-sorting__button-badge">
<span className="es-sfs-button-badge es-sfs-sorting__button-badge">
{values[0].direction === 'asc' ? iconAsc : iconDesc}
</div>
</span>
)}
{values.length > 1 && (
<div className="es-sfs-button-badge es-sfs-sorting__button-badge mini200">{values.length}</div>
<span className="es-sfs-button-badge es-sfs-sorting__button-badge mini200">{values.length}</span>
)}
</SFSButton>
<SortingMenu
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ export const SidebarItem: OverridableComponent<SidebarItemTypeMap> = ({ ref: inR
<span className="body100">{text}</span>
</MenuItem>

{!!children && <Divider className="es-sidebar-item__tooltip-divider" />}
{!!children && <Divider className="es-sidebar-item__tooltip-divider" component="li" role="presentation" />}
{!!children &&
React.Children.map(children, (child: any, idx: number) => {
const { text, inset, onClick, ...rest } = child.props;
Expand Down Expand Up @@ -263,6 +263,7 @@ export const SidebarItem: OverridableComponent<SidebarItemTypeMap> = ({ ref: inR
ref={itemRef}
button
className={clsx('es-sidebar-item__button', `es-sidebar-item__button--color--${color}`)}
{...({ component: 'div' } as any)}
onClick={onItemClick}
onKeyDown={onItemKeyDown}
onTouchStart={onItemTouchStart}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ export const SidenavItem: OverridableComponent<SidenavItemTypeMap> = ({ ref: inR
ref={itemRef}
button
className={clsx('es-sidenav-item', `es-sidenav-item--color--${color}`, className)}
{...({ component: 'div' } as any)}
data-id={id}
selected={selected}
onClick={onItemClick}
Expand Down
4 changes: 2 additions & 2 deletions packages/react/src/components/Slider/useSlider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -664,8 +664,8 @@ export function useSlider(parameters: UseSliderParameters): UseSliderReturnValue
tabIndex,
'aria-labelledby': ariaLabelledby,
'aria-orientation': orientation,
'aria-valuemax': scale(max),
'aria-valuemin': scale(min),
'aria-valuemax': scale(max) === max ? undefined : scale(max),
'aria-valuemin': scale(min) === min ? undefined : scale(min),
name,
type: 'range',
min: parameters.min,
Expand Down
4 changes: 2 additions & 2 deletions packages/react/src/components/SortingMenu/SortingMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,10 @@ export const SortingMenu = memo(function SortingMenu({
? sortMap[item.value].labelAsc || labelAsc
: sortMap[item.value].labelDesc || labelDesc}
</span>
<div className="es-sorting-menu__direction-button-badge">
<span className="es-sorting-menu__direction-button-badge">
{item.direction === 'asc' ? iconItemAsc : iconItemDesc}
{isMultiple && <span className="mini100-w50">{i + 1}</span>}
</div>
</span>
</Button>
)}
</MenuItem>
Expand Down
Loading
Loading