-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(Buttons): Leading + trailing icons
Adds standardized leading and trailing icons to our Fill, Stroke, and TextButtons.
- Loading branch information
Showing
15 changed files
with
243 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,20 @@ | ||
import { createButtonComponent } from './shared'; | ||
import { fillButtonVariants, sizeVariants } from './variants'; | ||
import { forwardRef } from 'react'; | ||
|
||
export const FillButton = createButtonComponent( | ||
import { ButtonBaseElements } from '../ButtonBase/ButtonBase'; | ||
import { | ||
createButtonComponent, | ||
fillButtonVariants, | ||
InlineIconButton, | ||
InlineIconButtonProps, | ||
sizeVariants, | ||
fillButtonVariants | ||
} from './shared'; | ||
|
||
const FillButtonBase = createButtonComponent(sizeVariants, fillButtonVariants); | ||
|
||
export type FillButtonProps = InlineIconButtonProps<typeof FillButtonBase>; | ||
|
||
export const FillButton = forwardRef<ButtonBaseElements, FillButtonProps>( | ||
({ ...props }, ref) => { | ||
return <InlineIconButton button={FillButtonBase} {...props} ref={ref} />; | ||
} | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,23 @@ | ||
import { createButtonComponent } from './shared'; | ||
import { sizeVariants, strokeButtonVariants } from './variants'; | ||
import { forwardRef } from 'react'; | ||
|
||
export const StrokeButton = createButtonComponent( | ||
import { ButtonBaseElements } from '../ButtonBase/ButtonBase'; | ||
import { | ||
createButtonComponent, | ||
InlineIconButton, | ||
InlineIconButtonProps, | ||
sizeVariants, | ||
strokeButtonVariants, | ||
} from './shared'; | ||
|
||
const StrokeButtonBase = createButtonComponent( | ||
sizeVariants, | ||
strokeButtonVariants | ||
); | ||
|
||
export type StrokeButtonProps = InlineIconButtonProps<typeof StrokeButtonBase>; | ||
|
||
export const StrokeButton = forwardRef<ButtonBaseElements, StrokeButtonProps>( | ||
({ ...props }, ref) => { | ||
return <InlineIconButton button={StrokeButtonBase} {...props} ref={ref} />; | ||
} | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,20 @@ | ||
import { createButtonComponent } from './shared'; | ||
import { sizeVariants, textButtonVariants } from './variants'; | ||
import { forwardRef } from 'react'; | ||
|
||
export const TextButton = createButtonComponent( | ||
import { ButtonBaseElements } from '../ButtonBase/ButtonBase'; | ||
import { | ||
createButtonComponent, | ||
InlineIconButton, | ||
InlineIconButtonProps, | ||
sizeVariants, | ||
textButtonVariants, | ||
sizeVariants | ||
} from './shared'; | ||
|
||
const TextButtonBase = createButtonComponent(textButtonVariants, sizeVariants); | ||
|
||
export type TextButtonProps = InlineIconButtonProps<typeof TextButtonBase>; | ||
|
||
export const TextButton = forwardRef<ButtonBaseElements, TextButtonProps>( | ||
({ ...props }, ref) => { | ||
return <InlineIconButton button={TextButtonBase} {...props} ref={ref} />; | ||
} | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { StarIcon } from '@codecademy/gamut-icons'; | ||
import { fireEvent } from '@testing-library/react'; | ||
import { setupRtl } from 'component-test-setup'; | ||
|
||
import { TextButton } from '../TextButton'; | ||
|
||
const onClick = jest.fn(); | ||
|
||
const renderView = setupRtl(TextButton, { | ||
children: 'Click me!', | ||
onClick, | ||
}); | ||
|
||
describe('TextButton', () => { | ||
it('renders a clickable button', () => { | ||
const { view } = renderView(); | ||
|
||
const cta = view.getByRole('button', { name: 'Click me!' }); | ||
|
||
fireEvent.click(cta); | ||
|
||
expect(onClick).toHaveBeenCalled(); | ||
}); | ||
it('renders an leading icon when an icon is provided', () => { | ||
const { view } = renderView({ icon: StarIcon }); | ||
|
||
view.getByTitle('Star Icon'); | ||
}); | ||
it('renders an icon when an icon is provided', () => { | ||
const { view } = renderView({ icon: StarIcon }); | ||
|
||
view.getByTitle('Star Icon'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { forwardRef } from 'react'; | ||
|
||
import { FlexBox } from '../../Box'; | ||
import { ButtonBaseElements } from '../../ButtonBase/ButtonBase'; | ||
import { FillButtonProps } from '../FillButton'; | ||
import { StrokeButtonProps } from '../StrokeButton'; | ||
import { TextButtonProps } from '../TextButton'; | ||
|
||
type InlineIconButtonComponents = | ||
| FillButtonProps | ||
| StrokeButtonProps | ||
| TextButtonProps; | ||
|
||
type InlineIconButtonType = InlineIconButtonComponents & { | ||
button: React.ComponentType<InlineIconButtonComponents>; | ||
}; | ||
|
||
const getButtonContent = ({ | ||
iconPosition, | ||
icon: Icon, | ||
children, | ||
}: Pick<InlineIconButtonType, 'iconPosition' | 'icon' | 'children'>) => { | ||
const iconSpacing = iconPosition === 'left' ? 'mr' : 'ml'; | ||
const iconPositioning = iconPosition === 'left' ? 0 : 1; | ||
|
||
const iconProps = { | ||
'aria-hidden': true, | ||
size: 12, | ||
[iconSpacing]: 8, | ||
order: iconPositioning, | ||
} as const; | ||
|
||
return !Icon ? ( | ||
<>{children}</> | ||
) : ( | ||
<FlexBox center height="100%"> | ||
{Icon && <Icon {...iconProps} />} | ||
{children} | ||
</FlexBox> | ||
); | ||
}; | ||
|
||
export const InlineIconButton = forwardRef< | ||
ButtonBaseElements, | ||
InlineIconButtonType | ||
>( | ||
( | ||
{ | ||
children, | ||
button: Button, | ||
icon, | ||
iconPosition = 'left', | ||
variant, | ||
...props | ||
}, | ||
ref | ||
) => { | ||
const content = getButtonContent({ iconPosition, icon, children }); | ||
return ( | ||
<Button {...props} variant={variant} ref={ref}> | ||
{content} | ||
</Button> | ||
); | ||
} | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export * from './InlineIconButton'; | ||
export * from './styles'; | ||
export * from './types'; | ||
export * from './variants'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { GamutIconProps } from '@codecademy/gamut-icons'; | ||
import { ColorModes } from '@codecademy/gamut-styles'; | ||
import { StyleProps } from '@codecademy/variance'; | ||
import { ComponentProps, HTMLProps } from 'react'; | ||
|
||
import { ButtonBase } from '../../ButtonBase'; | ||
import { CTAButton } from '../CTAButton'; | ||
import { FillButton } from '../FillButton'; | ||
import { IconButton } from '../IconButton'; | ||
import { StrokeButton } from '../StrokeButton'; | ||
import { TextButton } from '../TextButton'; | ||
import { buttonProps, buttonVariants } from './styles'; | ||
|
||
export interface ButtonBaseProps extends StyleProps<typeof buttonProps> { | ||
onClick?: HTMLProps<HTMLButtonElement>['onClick']; | ||
variant?: typeof buttonVariants[number]; | ||
size?: 'normal' | 'small' | 'large'; | ||
as?: never; | ||
mode?: ColorModes; | ||
} | ||
|
||
export type ButtonProps = ButtonBaseProps & ComponentProps<typeof ButtonBase>; | ||
export type IconComponentType = { icon: React.ComponentType<GamutIconProps> }; | ||
|
||
export type InlineIconButtonProps< | ||
BaseButtonType extends | ||
| keyof JSX.IntrinsicElements | ||
| React.JSXElementConstructor<any> | ||
> = ComponentProps<BaseButtonType> & | ||
Partial<IconComponentType> & { | ||
iconPosition?: 'right' | 'left'; | ||
}; | ||
|
||
export type ButtonTypes = | ||
| typeof CTAButton | ||
| typeof FillButton | ||
| typeof IconButton | ||
| typeof StrokeButton | ||
| typeof TextButton; |
4 changes: 2 additions & 2 deletions
4
packages/gamut/src/Button/variants.ts → packages/gamut/src/Button/shared/variants.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.