Skip to content

Commit

Permalink
feat: add icon handling
Browse files Browse the repository at this point in the history
  • Loading branch information
skinread committed Dec 20, 2024
1 parent 6a4d0a9 commit b5e6793
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 26 deletions.
4 changes: 3 additions & 1 deletion lib/components/Icon/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ import { Box, useBoxStyles } from '../Box';

import * as styles from './Icon.css';

export type IconEl = IconType | ReactElement<SVGAttributes<SVGElement>, 'svg'>;

export interface Props {
display?: Extract<BoxStyleProps['display'], 'block' | 'inlineBlock'>;
className?: string;
size?: ResponsiveProp<keyof typeof styles.size | string>;
icon: IconType | ReactElement<SVGAttributes<SVGElement>, 'svg'>;
icon: IconEl;
}

export const Icon: FunctionComponent<Props> = ({
Expand Down
2 changes: 1 addition & 1 deletion lib/components/Icon/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { Icon } from './Icon';
export { Icon, type IconEl, type Props as IconProps } from './Icon';
21 changes: 5 additions & 16 deletions lib/components/IconCheckboxButton/IconCheckboxButton.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ export type StyledWrapperProps = NonNullable<
RecipeVariants<typeof styledWrapper>
>;

export const iconContainer = style({
height: '26px',
width: '26px',
});

const checkboxBaseTransition = style({
transitionProperty: 'background',
transitionTimingFunction: 'ease-in',
Expand Down Expand Up @@ -77,19 +82,3 @@ export const styledCheckbox = recipe({
export type StyledCheckboxProps = NonNullable<
RecipeVariants<typeof styledCheckbox>
>;

export const styledIcon = recipe({
base: {
height: '26px',
width: '26px',
},
variants: {
hidden: {
true: {
display: 'none',
},
},
},
});

export type StyledIconProps = NonNullable<RecipeVariants<typeof styledIcon>>;
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { AirconIcon } from '@autoguru/icons';
import type { Meta, StoryObj } from '@storybook/react';
import { expect, fn, getAllByRole, within, userEvent } from '@storybook/test';

Expand All @@ -7,9 +8,10 @@ const meta: Meta<typeof IconCheckboxButton> = {
title: 'Components/Icon Checkbox Button',
component: IconCheckboxButton,
args: {
children: 'Re-gas Air-conditioning',
label: 'Re-gas Air-conditioning',
icon: AirconIcon,
name: 'extras',
className: 'demo-checkbox-buttons-class',
// className: 'demo-checkbox-buttons-class',
onChange: fn(),
},
tags: ['beta'],
Expand Down
29 changes: 23 additions & 6 deletions lib/components/IconCheckboxButton/IconCheckboxButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,29 @@ import { useCheckbox, useFocusRing, useHover } from 'react-aria';
import type { AriaCheckboxProps } from 'react-aria';
import { useToggleState } from 'react-stately';

import { Icon, type IconEl } from '../Icon';
import { VisuallyHidden } from '../VisuallyHidden';

import {
iconContainer,
styledCheckbox,
styledIcon,
styledWrapper,
type StyledWrapperProps,
} from './IconCheckboxButton.css';

interface IconCheckboxButtonProps extends AriaCheckboxProps {
icon?: React.ReactNode;
/**
* The text label for the checkbox
*/
label: string;
/**
* Source an icon from `@autoguru/icons`
*/
icon?: IconEl;
/**
* Additional text description content for the checkbox button
*/
description?: string;
className?: string;
}

Expand Down Expand Up @@ -48,16 +60,17 @@ const Wrapper = (props: PropsWithChildren<StyledWrapperProps>) => {
};

export const IconCheckboxButton = ({
description,
icon,
label,
...props
}: IconCheckboxButtonProps) => {
const ref = useRef<HTMLInputElement>(null);
const state = useToggleState(props);
const { inputProps, isSelected } = useCheckbox(props, state, ref);
const { focusProps, isFocusVisible } = useFocusRing();
const { hoverProps, isHovered } = useHover({});
const hasIcon = !!icon;
const showCheckbox = !hasIcon || isHovered || isSelected;
const showCheckbox = !icon || isHovered || isSelected;

return (
<Wrapper
Expand All @@ -70,7 +83,7 @@ export const IconCheckboxButton = ({
<VisuallyHidden>
<input {...inputProps} ref={ref} />
</VisuallyHidden>
<div>
<div className={iconContainer}>
{showCheckbox ? (
<div
className={styledCheckbox()}
Expand All @@ -80,9 +93,13 @@ export const IconCheckboxButton = ({
<IconTick />
</div>
) : (
<div className={styledIcon()}>{icon}</div>
<Icon icon={icon} size="100%" />
)}
</div>
<div>
<span>{label}</span>
<span>{description}</span>
</div>
</Wrapper>
);
};

0 comments on commit b5e6793

Please sign in to comment.