Skip to content

Commit

Permalink
Added prop removePadding to support compact view of the Button compon…
Browse files Browse the repository at this point in the history
…ent withouth height, width and padding
  • Loading branch information
ksolanki7 committed Dec 17, 2024
1 parent 31543eb commit 3b7a012
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 41 deletions.
8 changes: 8 additions & 0 deletions src/components/button/button.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ With href prop, link can be displayed as button. Anchor attributes such as `targ
<Canvas of={ButtonStories.ButtonWithHref} />
<RenderHtmlMarkup of={ButtonStories.ButtonWithHref} />

## Button With removePadding

The `removePadding` prop is used with the `tertiary` variant of the button to demonstrate how removing padding and resetting the height can create a more minimalistic, compact button style.
This is useful when you need a button with no extra spacing or fixed height, while maintaining the button's core functionality and appearance. The prop is designed exclusively for the tertiary variant and will not affect other button variant types.

<Canvas of={ButtonStories.ButtonWithRemovePadding} />
<RenderHtmlMarkup of={ButtonStories.ButtonWithRemovePadding} />

## Other attributes

All other standard HTML attributes for `<button>` are supported and are passed through to the React component, e.g. type and onClick
Expand Down
16 changes: 15 additions & 1 deletion src/components/button/button.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ButtonGroup } from '../button-group'
import { action } from '@storybook/addon-actions'
import { Icon, IconNames } from '../icon'

const ICON_OPTIONS: IconNames[] = ['star', 'check', 'add', 'arrowDown', 'email']
const ICON_OPTIONS: IconNames[] = ['star', 'check', 'add', 'chevronDown', 'email']

const meta: Meta<typeof Button> = {
title: 'Components/Button',
Expand Down Expand Up @@ -52,6 +52,11 @@ const meta: Meta<typeof Button> = {
control: 'text',
description: 'CSS class for additional styling',
},
removePadding: {
control: 'boolean',
description:
'Set this prop to true to remove the padding and height adjustments for the tertiary variant of the button. This will apply no padding and reset the height, giving a more compact button appearance. It is only applicable when the button variant is tertiary.',
},
},
}

Expand Down Expand Up @@ -145,6 +150,15 @@ export const ButtonWithHref = {
),
}

export const ButtonWithRemovePadding = {
name: 'Button With RemovePadding',
args: {
children: 'Button Text',
variant: 'tertiary',
removePadding: true,
},
}

export const StandardAttributes = {
name: 'Standard attributes',

Expand Down
100 changes: 60 additions & 40 deletions src/components/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
elButtonGroupAlignRight,
elButtonGroupAlignCenter,
ElButtonLabel,
elButtonRemovePadding,
} from './styles'
import { Icon, IconNames } from '../icon'
import { cx } from '@linaria/core'
Expand All @@ -33,7 +34,6 @@ type ButtonAsAnchorVariant = Exclude<ButtonAsButtonVariant, 'busy'>

interface CommonButtonProps {
children?: ReactNode
variant?: ButtonAsButtonVariant
size?: ButtonSize
iconLeft?: ReactNode
iconRight?: ReactNode
Expand All @@ -42,38 +42,51 @@ interface CommonButtonProps {
className?: string
}

interface ButtonAsButtonElementProps extends CommonButtonProps, ButtonHTMLAttributes<HTMLButtonElement> {
href?: never
target?: never
disabled?: boolean
onClick?: MouseEventHandler<HTMLButtonElement>
// Define a specialized type for tertiary variant for prop removePadding
type TertiaryButtonProps = {
variant: 'tertiary'
removePadding?: boolean // Only tertiary buttons can use removePadding
}

interface ButtonAsAnchorElementProps extends CommonButtonProps, AnchorHTMLAttributes<HTMLAnchorElement> {
variant?: ButtonAsAnchorVariant
/** Button styled <a> element should always have href */
href: string
target?: string
rel?: string
/** Anchor elements cannot be disabled. Use a button element if the component needs to be in a disabled state */
disabled?: never
onClick?: MouseEventHandler<HTMLAnchorElement>
// Define the general type for non-tertiary variants
type NonTertiaryButtonProps = {
variant?: Exclude<ButtonAsButtonVariant, 'tertiary'>
removePadding?: never // Disallow removePadding for other variants
}

// Combine the above two into a Variant-specific prop type
type VariantSpecificProps = TertiaryButtonProps | NonTertiaryButtonProps

type ButtonAsButtonElementProps = CommonButtonProps &
VariantSpecificProps &
ButtonHTMLAttributes<HTMLButtonElement> & {
href?: never
target?: never
disabled?: boolean
onClick?: MouseEventHandler<HTMLButtonElement>
}

type ButtonAsAnchorElementProps = CommonButtonProps &
VariantSpecificProps &
AnchorHTMLAttributes<HTMLAnchorElement> & {
variant?: ButtonAsAnchorVariant
/** Button styled <a> element should always have href */
href: string
target?: string
rel?: string
/** Anchor elements cannot be disabled. Use a button element if the component needs to be in a disabled state */
disabled?: never
onClick?: MouseEventHandler<HTMLAnchorElement>
}

export type ButtonProps = ButtonAsButtonElementProps | ButtonAsAnchorElementProps

function isButtonAsButtonElement(props: ButtonProps): props is ButtonAsButtonElementProps {
return !props.href
}

export const handleButtonClick =
(onClick?: MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>) =>
(e: MouseEvent<HTMLButtonElement | HTMLAnchorElement>) => {
if (onClick) onClick(e)
}

/** @deprecated */
export interface FloatingButtonProps extends ButtonAsButtonElementProps {
export type FloatingButtonProps = ButtonAsButtonElementProps & {
icon: IconNames
}

Expand All @@ -87,21 +100,23 @@ export interface ButtonGroupProps extends HTMLAttributes<HTMLDivElement> {
alignment?: ButtonGroupAlignment
}

export const Button: FC<ButtonProps> = ({
children,
variant,
size = 'medium',
iconLeft,
iconRight,
onClick,
'aria-label': ariaLabel,
disabled = false,
href,
target,
rel,
className,
...rest
}) => {
export const Button: FC<ButtonProps> = (props) => {
const {
children,
variant,
size = 'medium',
iconLeft,
iconRight,
'aria-label': ariaLabel,
disabled = false,
href,
target,
rel,
className,
removePadding,
...rest
} = props

const sizeClass = cx(
size === 'small' && elButtonSizeSmall,
size === 'medium' && elButtonSizeMedium,
Expand All @@ -110,18 +125,21 @@ export const Button: FC<ButtonProps> = ({

const miscellaneousClass = cx(
!children && elButtonIconOnly, // if no children(label) then add el-button-icon-only class
removePadding && elButtonRemovePadding, // To remove height and padding from the button component
)

const combinedClassName = cx(className, sizeClass, miscellaneousClass)

if (!isButtonAsButtonElement({ href })) {
if (!isButtonAsButtonElement(props)) {
return (
<ElAnchorButton
href={href}
data-variant={variant}
className={combinedClassName}
onClick={(e) => {
handleButtonClick(onClick)(e)
if (props.onClick) {
props.onClick(e)
}
}}
aria-label={ariaLabel}
role="button"
Expand All @@ -142,7 +160,9 @@ export const Button: FC<ButtonProps> = ({
className={combinedClassName}
onClick={(e) => {
if (!disabled) {
handleButtonClick(onClick)(e)
if (props.onClick) {
props.onClick(e)
}
} else {
e.preventDefault() // Explicitly prevent default if disabled
}
Expand Down
6 changes: 6 additions & 0 deletions src/components/button/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const elButtonLabel = css``
export const elIcon = css``
export const elButtonIconOnly = css``
export const elButtonSpinner = css``
export const elButtonRemovePadding = css``

/** @deprecated - Will be removed from future version */
export const elFloatingButton = css``
Expand Down Expand Up @@ -143,6 +144,11 @@ const baseButtonStyles = `
color: var(--icon-secondary);
}
}
&.${elButtonRemovePadding} {
height: unset;
width: unset; /* To unset width for iconOnly button */
padding: 0px;
}
}
&[data-variant='destructive'] {
Expand Down

0 comments on commit 3b7a012

Please sign in to comment.