Skip to content

Commit

Permalink
fix(components): radio, accordion and text-link (#48)
Browse files Browse the repository at this point in the history
  • Loading branch information
danielsimao authored Jan 16, 2024
1 parent efa2a71 commit bfafd59
Show file tree
Hide file tree
Showing 11 changed files with 91 additions and 56 deletions.
5 changes: 5 additions & 0 deletions .changeset/tidy-kiwis-lick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@interlay/ui": patch
---

fix(components): radio, accordion and textLink
23 changes: 14 additions & 9 deletions packages/components/src/Accordion/Accordion.style.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ type StyledAccordionItemButtonProps = {
};

type StyledAccordionItemRegionProps = {
$height: number;
$isExpanded: boolean;
};

type StyledAccordionItemContentProps = {
$isExpanded: boolean;
};

Expand Down Expand Up @@ -53,16 +56,18 @@ const StyledChevronDown = styled(ChevronDown)<Pick<StyledAccordionProps, '$isExp
`;

const StyledAccordionItemRegion = styled.div<StyledAccordionItemRegionProps>`
overflow: hidden;
opacity: ${({ $isExpanded }) => ($isExpanded ? 1 : 0)};
height: ${({ $isExpanded, $height }) => ($isExpanded ? `${$height}px` : 0)};
transition:
height 200ms ease 0ms,
opacity 300ms ease 0ms;
display: grid;
grid-template-rows: ${(props) => (props.$isExpanded ? '1fr' : '0fr')};
transition: all 200ms ease 0ms;
`;

const StyledAccordionItemContent = styled.div`
padding: 0 ${theme.spacing.spacing4} ${theme.spacing.spacing4} ${theme.spacing.spacing4};
const StyledAccordionItemContent = styled.div<StyledAccordionItemContentProps>`
overflow: hidden;
padding-top: 0;
padding-left: ${theme.spacing.spacing4};
padding-right: ${theme.spacing.spacing4};
padding-bottom: ${({ $isExpanded }) => ($isExpanded ? theme.spacing.spacing4 : 0)};
transition: all 200ms ease 0ms;
`;

export {
Expand Down
14 changes: 3 additions & 11 deletions packages/components/src/Accordion/AccordionItemRegion.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { HTMLAttributes, useEffect, useRef, useState } from 'react';
import { HTMLAttributes } from 'react';

import { StyledAccordionItemContent, StyledAccordionItemRegion } from './Accordion.style';

Expand All @@ -11,17 +11,9 @@ type NativeAttrs = Omit<HTMLAttributes<unknown>, keyof Props>;
type AccordionItemRegionProps = Props & NativeAttrs;

const AccordionItemRegion = ({ isExpanded, children, ...props }: AccordionItemRegionProps): JSX.Element => {
const ref = useRef<HTMLDivElement | null>(null);
const [height, setHeight] = useState<number>(0);

// Updates height in case anything changed in children
useEffect(() => {
setHeight(ref.current?.clientHeight || 0);
}, [isExpanded]);

return (
<StyledAccordionItemRegion {...props} $height={height} $isExpanded={isExpanded}>
<StyledAccordionItemContent ref={ref}>{children}</StyledAccordionItemContent>
<StyledAccordionItemRegion {...props} $isExpanded={isExpanded}>
<StyledAccordionItemContent $isExpanded={isExpanded}>{children}</StyledAccordionItemContent>
</StyledAccordionItemRegion>
);
};
Expand Down
8 changes: 6 additions & 2 deletions packages/components/src/Radio/Radio.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ import { Radio, RadioGroupProps, RadioGroup } from '.';

const Render = (args: RadioGroupProps) => (
<RadioGroup {...args} label='Coin'>
<Radio value='BTC'>BTC</Radio>
<Radio value='ETH'>ETH</Radio>
<Radio flex value='BTC'>
BTC
</Radio>
<Radio flex value='ETH'>
ETH
</Radio>
</RadioGroup>
);

Expand Down
4 changes: 4 additions & 0 deletions packages/components/src/Radio/Radio.style.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type StyledRadioGroupProps = {

type StyledLabelProps = {
$isDisabled?: boolean;
$flex?: number | string | boolean;
};

type StyledButtonProps = {
Expand All @@ -20,6 +21,8 @@ type StyledButtonProps = {
};

const StyledRadioGroup = styled(Flex)<StyledRadioGroupProps>`
width: 100%;
label {
margin-right: ${({ $orientation, $gap }) => $orientation === 'horizontal' && $gap && theme.spacing[$gap]};
margin-bottom: ${({ $orientation, $gap }) => $orientation === 'vertical' && $gap && theme.spacing[$gap]};
Expand All @@ -32,6 +35,7 @@ const StyledLabel = styled(Label)<StyledLabelProps>`
gap: ${theme.spacing.spacing2};
align-items: center;
opacity: ${({ $isDisabled }) => $isDisabled && 0.5};
flex: ${({ $flex }) => (typeof $flex === 'boolean' ? '1' : $flex)};
`;

const StyledInput = styled.input`
Expand Down
6 changes: 4 additions & 2 deletions packages/components/src/Radio/Radio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ import { HTMLAttributes, forwardRef, useRef } from 'react';

import { Span, TextProps } from '../Text';

import { useRadioProvider } from './RadioContext';
import { StyledButton, StyledInput, StyledLabel } from './Radio.style';
import { useRadioProvider } from './RadioContext';

type Props = {
labelProps?: TextProps;
labelPlacement?: Extract<Placement, 'left' | 'right'>;
flex?: string | number | boolean;
};

type NativeAttrs = Omit<HTMLAttributes<unknown>, keyof Props>;
Expand All @@ -22,7 +23,7 @@ type RadioProps = Props & NativeAttrs & InheritAttrs;

// TODO: determine if isInvalid is necessary
const Radio = forwardRef<HTMLLabelElement, RadioProps>(
({ labelProps, isDisabled: isDisabledProp, children, className, style, ...props }, ref): JSX.Element => {
({ labelProps, isDisabled: isDisabledProp, children, className, style, flex, ...props }, ref): JSX.Element => {
let { hoverProps, isHovered } = useHover({ isDisabled: isDisabledProp });

const labelRef = useDOMRef(ref);
Expand All @@ -45,6 +46,7 @@ const Radio = forwardRef<HTMLLabelElement, RadioProps>(
{...labelProps}
{...hoverProps}
ref={labelRef}
$flex={flex}
$isDisabled={isDisabled}
className={className}
style={style}
Expand Down
6 changes: 6 additions & 0 deletions packages/components/src/TextLink/TextLink.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,9 @@ export const External: StoryObj<TextLinkProps> = {
icon: true
}
};

export const WithoutHref: StoryObj<TextLinkProps> = {
args: {
href: undefined
}
};
6 changes: 3 additions & 3 deletions packages/components/src/TextLink/TextLink.style.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Colors, FontSize, FontWeight } from '@interlay/theme';

type BaseTextLinkProps = {
$color?: Colors;
$underlined?: boolean;
$isQuiet?: boolean;
$size?: FontSize;
$weight?: FontWeight;
};
Expand All @@ -17,11 +17,11 @@ const BaseTextLink = styled.a<BaseTextLinkProps>`
font-size: ${({ $size }) => $size && theme.text[$size]};
line-height: ${({ $size }) => resolveHeight($size)};
font-weight: ${({ $weight }) => $weight && theme.fontWeight[$weight]};
text-decoration: ${(props) => props.$underlined && 'underline'};
text-decoration: ${(props) => (props.$isQuiet ? 'none' : 'underline')};
&:hover,
&:focus-visible {
text-decoration: ${(props) => (props.$underlined ? 'underline double' : 'underline')};
text-decoration: underline;
}
`;

Expand Down
23 changes: 16 additions & 7 deletions packages/components/src/TextLink/TextLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { BaseTextLink, StyledIcon } from './TextLink.style';
type Props = {
color?: Colors;
external?: boolean;
underlined?: boolean;
isQuiet?: boolean;
size?: FontSize;
weight?: FontWeight;
icon?: boolean;
Expand All @@ -23,12 +23,21 @@ type TextLinkProps = Props & NativeAttrs & AriaAttrs;

// TODO: merge this with CTALink
const TextLink = forwardRef<HTMLAnchorElement, TextLinkProps>(
({ color = 'primary', external, underlined, size, weight, icon, children, ...props }, ref): JSX.Element => {
(
{ color = 'primary', external, isQuiet, size, weight, icon, children, href, className, ...props },
ref
): JSX.Element => {
const linkRef = useDOMRef(ref);

const elementType = href ? 'a' : 'span';

const externalProps = external ? { target: '_blank', rel: 'noreferrer' } : undefined;

const ariaProps = {
...props,
...(external && { target: '_blank', rel: 'noreferrer' })
...externalProps,
href,
elementType
};

const { linkProps } = useLink(ariaProps, linkRef);
Expand All @@ -37,12 +46,12 @@ const TextLink = forwardRef<HTMLAnchorElement, TextLinkProps>(
<BaseTextLink
ref={linkRef}
$color={color}
$isQuiet={!href || isQuiet}
$size={size}
$underlined={underlined}
$weight={weight}
{...mergeProps(props, linkProps, {
...(external && { target: '_blank', rel: 'noreferrer' })
})}
as={elementType}
className={className}
{...mergeProps(linkProps, externalProps)}
>
{children}
{icon && <StyledIcon />}
Expand Down
10 changes: 9 additions & 1 deletion packages/components/src/TextLink/__tests__/TextLink.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { render } from '@testing-library/react';
import { render, screen } from '@testing-library/react';
import { createRef } from 'react';
import { testA11y } from '@interlay/test-utils';

Expand All @@ -22,4 +22,12 @@ describe('TextLink', () => {
it('should pass a11y', async () => {
await testA11y(<TextLink>link</TextLink>);
});

it('should render pressable link as a span', async () => {
const handlePress = jest.fn();

render(<TextLink onPress={handlePress}>link</TextLink>);

expect(screen.getByRole('link').tagName).toBe('SPAN');
});
});
42 changes: 21 additions & 21 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit bfafd59

Please sign in to comment.