Skip to content

Commit

Permalink
feat(Link): implement link component (#953)
Browse files Browse the repository at this point in the history
  • Loading branch information
hebernardEquisoft authored Oct 22, 2024
1 parent ac166db commit 512bb43
Show file tree
Hide file tree
Showing 47 changed files with 2,593 additions and 919 deletions.
2 changes: 1 addition & 1 deletion packages/react/src/components/breadcrumb/breadcrumb.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { KeyboardEvent, useCallback, useEffect, useRef, useState, VoidFunctionCo
import { Link } from 'react-router-dom';
import styled from 'styled-components';
import { eventIsInside } from '../../utils/events';
import { IconButton } from '../buttons/icon-button';
import { IconButton } from '../buttons';
import { Icon } from '../icon/icon';
import { NavList } from '../nav-list/nav-list';
import { NavListOption } from '../nav-list/nav-list-option';
Expand Down
144 changes: 0 additions & 144 deletions packages/react/src/components/buttons/abstract-button.tsx

This file was deleted.

29 changes: 29 additions & 0 deletions packages/react/src/components/buttons/abstract/abstract-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { forwardRef, PropsWithChildren, Ref } from 'react';
import { useDeviceContext } from '../../device-context-provider/device-context-provider';
import { StyledAbstractButton } from './styled';
import { AbstractButtonProps } from './types';

export const AbstractButton = forwardRef<HTMLButtonElement, PropsWithChildren<AbstractButtonProps>>(({
children,
onClick,
focusable,
...props
}: AbstractButtonProps, ref: Ref<HTMLButtonElement>) => {
const { isMobile } = useDeviceContext();

return (
<StyledAbstractButton
$focusable={focusable}
$isMobile={isMobile}
onClick={onClick}
ref={ref}
tabIndex={focusable === false ? -1 : undefined}
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
>
{children}
</StyledAbstractButton>
);
});

AbstractButton.displayName = 'AbstractButton';
70 changes: 70 additions & 0 deletions packages/react/src/components/buttons/abstract/styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import styled, { css, FlattenInterpolation, ThemeProps } from 'styled-components';
import { ResolvedTheme } from '../../../themes/theme';
import { focus } from '../../../utils/css-state';
import { Size } from './types';

export interface BaseButtonStyles {
$size?: Size;
$isMobile: boolean;
$focusable?: boolean;
$inverted?: boolean;
}

function getButtonMinHeight({ $isMobile, $size }: BaseButtonStyles): string {
switch ($size) {
case 'small':
return $isMobile ? 'var(--size-3x)' : 'var(--size-1halfx)';
case 'medium':
default:
return $isMobile ? 'var(--size-3x)' : 'var(--size-2x)';
}
}

function getButtonPadding({ $isMobile, $size }: BaseButtonStyles): string {
switch ($size) {
case 'small':
return $isMobile ? '0 var(--spacing-3x);' : '0 var(--spacing-1halfx);';
case 'medium':
default:
return $isMobile ? '0 var(--spacing-3x);' : '0 var(--spacing-2x);';
}
}

export const getBaseButtonStyles = ({
$size,
$isMobile,
$focusable,
$inverted,
}: BaseButtonStyles): FlattenInterpolation<ThemeProps<ResolvedTheme>> => css`
align-items: center;
appearance: none;
background: inherit;
border: 1px solid;
border-radius: 1.5rem;
box-sizing: border-box;
color: inherit;
display: inline-flex;
font-family: inherit;
font-size: ${$isMobile ? 0.875 : 0.75}rem;
font-weight: var(--font-bold);
justify-content: center;
letter-spacing: ${$isMobile ? 0.033125 : 0.025}rem;
line-height: ${$isMobile ? 1.5 : 1}rem;
min-height: ${getButtonMinHeight({ $isMobile, $size })};
min-width: 2rem;
outline: none;
padding: ${getButtonPadding({ $isMobile, $size })};
text-transform: uppercase;
user-select: none;
${({ theme }) => $focusable !== false && focus({ theme }, { inverted: $inverted })};
> svg {
height: ${$isMobile ? 'var(--size-1halfx)' : 'var(--size-1x)'};
width: ${$isMobile ? 'var(--size-1halfx)' : 'var(--size-1x)'};
}
`;

export const StyledAbstractButton = styled.button<BaseButtonStyles>`
${getBaseButtonStyles};
`;
9 changes: 9 additions & 0 deletions packages/react/src/components/buttons/abstract/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { ButtonHTMLAttributes } from 'react';

export type Size = 'small' | 'medium';

export interface AbstractButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
focusable?: boolean;
isMobile: boolean;
size?: Size;
}
20 changes: 10 additions & 10 deletions packages/react/src/components/buttons/button.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -465,14 +465,6 @@ exports[`Button has left and right icons 1`] = `
width: var(--size-1x);
}
.c2 {
margin-right: var(--spacing-1x);
}
.c3 {
margin-left: var(--spacing-1x);
}
.c1 {
background-color: #006296;
border-color: #006296;
Expand Down Expand Up @@ -504,6 +496,14 @@ exports[`Button has left and right icons 1`] = `
cursor: not-allowed;
}
.c2 {
margin-right: var(--spacing-1x);
}
.c3 {
margin-left: var(--spacing-1x);
}
<button
class="c0 c1"
type="button"
Expand Down Expand Up @@ -1137,10 +1137,10 @@ exports[`Button has small styles 1`] = `
-ms-letter-spacing: 0.025rem;
letter-spacing: 0.025rem;
line-height: 1rem;
min-height: var(--size-1halfx);
min-height: var(--size-2x);
min-width: 2rem;
outline: none;
padding: 0 var(--spacing-1halfx);
padding: 0 var(--spacing-2x);
text-transform: uppercase;
-webkit-user-select: none;
-moz-user-select: none;
Expand Down
69 changes: 2 additions & 67 deletions packages/react/src/components/buttons/button.tsx
Original file line number Diff line number Diff line change
@@ -1,80 +1,15 @@
import {
FocusEventHandler,
forwardRef,
KeyboardEvent,
MouseEvent,
PropsWithChildren,
ReactElement,
Ref,
} from 'react';
import styled from 'styled-components';
import {
Icon,
IconName,
} from '../icon/icon';
import { Spinner } from '../spinner/spinner';
import { ResolvedTheme } from '../../themes/theme';
import { useTranslation } from '../../i18n/use-translation';
import { useDeviceContext } from '../device-context-provider/device-context-provider';
import { AbstractButton, ButtonType, getButtonTypeStyles } from './abstract-button';

export type Size = 'small' | 'medium';

export type Type = 'submit' | 'button' | 'reset';

export interface ButtonProps {
id?: string;
autofocus?: boolean;
/**
* Visual style
* @default primary
*/
buttonType: ButtonType;
className?: string;
disabled?: boolean;
/**
* @default true
*/
focusable?: boolean;
inverted?: boolean;
label?: string;
loading?: boolean;
/**
* @default Loading...
*/
loadingLabel?: string;
/**
* Size variant
* @default medium
*/
size?: Size;
title?: string;
type?: Type;

leftIconName?: IconName;
rightIconName?: IconName;

onClick?(event: MouseEvent<HTMLButtonElement>): void;
onFocus?: FocusEventHandler<HTMLButtonElement>;
onBlur?: FocusEventHandler<HTMLButtonElement>;
onKeyDown?(event: KeyboardEvent<HTMLButtonElement>): void;
}

const StyledSpinner = styled(Spinner)`
margin-right: var(--spacing-1x);
`;

const LeftIcon = styled(Icon)`
margin-right: var(--spacing-1x);
`;

const RightIcon = styled(Icon)`
margin-left: var(--spacing-1x);
`;

const StyledButton = styled(AbstractButton)<{ theme: ResolvedTheme } & ButtonProps>`
${getButtonTypeStyles}
`;
import { LeftIcon, RightIcon, StyledButton, StyledSpinner } from './styled';
import { ButtonProps } from './types';

export const Button = forwardRef<HTMLButtonElement, PropsWithChildren<ButtonProps>>(({
autofocus,
Expand Down
Loading

0 comments on commit 512bb43

Please sign in to comment.