Files
tom goriunovandGitHub 52f4141e76 Bump Chakra UI to v3.33.0 (#3292)
* Bump Chakra UI to v3.33.0

* disable typescript for ChakraCheckboxGroup ref prop

* fix button component

* change default value of SSR flag in useIsMobile hook

* some screenshot updates

* rollback screenshot
2026-02-25 14:53:35 +01:00

108 lines
3.4 KiB
TypeScript

import type { ButtonProps as ChakraButtonProps, ButtonGroupProps as ChakraButtonGroupProps } from '@chakra-ui/react';
import {
Button as ChakraButton,
ButtonGroup as ChakraButtonGroup,
} from '@chakra-ui/react';
import * as React from 'react';
import { Skeleton } from './skeleton';
interface ButtonLoadingProps {
loading?: boolean;
loadingText?: React.ReactNode;
loadingSkeleton?: boolean;
}
export interface ButtonProps extends ChakraButtonProps, ButtonLoadingProps {
expanded?: boolean;
selected?: boolean;
highlighted?: boolean;
}
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
function Button(props, ref) {
const { loading, disabled, children, expanded, selected, highlighted, loadingSkeleton = false, ...rest } = props;
return (
<Skeleton loading={ loadingSkeleton } asChild ref={ ref as React.ForwardedRef<HTMLDivElement> }>
<ChakraButton
{ ...(expanded ? { 'data-expanded': true } : {}) }
{ ...(selected ? { 'data-selected': true } : {}) }
{ ...(highlighted ? { 'data-highlighted': true } : {}) }
{ ...(loadingSkeleton ? { 'data-loading-skeleton': true } : {}) }
disabled={ !loadingSkeleton && (loading || disabled) }
loading={ loading }
{ ...rest }
>
{ children }
</ChakraButton>
</Skeleton>
);
},
);
export interface ButtonGroupProps extends ChakraButtonGroupProps {}
export const ButtonGroup = React.forwardRef<HTMLDivElement, ButtonGroupProps>(
function ButtonGroup(props, ref) {
const { ...rest } = props;
return (
<ChakraButtonGroup ref={ ref } { ...rest }/>
);
},
);
export interface ButtonGroupRadioProps extends Omit<ChakraButtonGroupProps, 'children' | 'onChange'> {
children: Array<React.ReactElement<ButtonProps>>;
onChange?: (value: string) => void;
defaultValue?: string;
loading?: boolean;
equalWidth?: boolean;
}
export const ButtonGroupRadio = React.forwardRef<HTMLDivElement, ButtonGroupRadioProps>(
function ButtonGroupRadio(props, ref) {
const { children, onChange, variant = 'segmented', defaultValue, loading = false, equalWidth = false, ...rest } = props;
const firstChildValue = React.useMemo(() => {
const firstChild = Array.isArray(children) ? children[0] : undefined;
return typeof firstChild?.props.value === 'string' ? firstChild.props.value : undefined;
}, [ children ]);
const [ value, setValue ] = React.useState<string | undefined>(defaultValue ?? firstChildValue);
const handleItemClick = React.useCallback((event: React.MouseEvent<HTMLButtonElement>) => {
const value = event.currentTarget.value;
setValue(value);
onChange?.(value);
}, [ onChange ]);
const clonedChildren = React.Children.map(children, (child: React.ReactElement<ButtonProps>) => {
return React.cloneElement(child, {
onClick: handleItemClick,
selected: value === child.props.value,
variant,
});
});
const childrenLength = React.Children.count(children);
return (
<Skeleton loading={ loading }>
<ChakraButtonGroup
ref={ ref }
gap={ 0 }
{ ...(equalWidth ? {
display: 'grid',
gridTemplateColumns: `repeat(${ childrenLength }, 1fr)`,
} : {}) }
{ ...rest }
>
{ clonedChildren }
</ChakraButtonGroup>
</Skeleton>
);
},
);