UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

132 lines (131 loc) 6.16 kB
/** * Web Button Component */ import React from 'react'; import type { SkeletonShow } from '../skeleton/Skeleton'; import type { IconIcon, IconSize } from '../icon/Icon'; import type { DataAttributes, DynamicElement, SpacingProps } from '../../shared/types'; import type { FormStatusBaseProps } from '../FormStatus'; import type { AnchorProps } from '../Anchor'; export type ButtonText = string | React.ReactNode; export type ButtonVariant = 'primary' | 'secondary' | 'tertiary' | 'unstyled'; export type ButtonSize = 'default' | 'small' | 'medium' | 'large'; export type ButtonIcon = IconIcon; export type ButtonIconPositionTertiary = 'top'; export type ButtonIconPosition = 'left' | 'right'; export type ButtonIconPositionAll = 'left' | 'right' | ButtonIconPositionTertiary; export type ButtonTooltip = string | (() => React.ReactNode) | React.ReactNode; export type ButtonTo = string | ReactRouterLink['to']; export type ButtonSkeleton = SkeletonShow; export type ButtonChildren = string | (() => React.ReactNode) | React.ReactNode; type ReactRouterLink = Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'href'> & { to: string | { pathname?: string; search?: string; has?: string; }; }; export type ButtonElement = DynamicElement<HTMLButtonElement | HTMLAnchorElement | AnchorProps> | React.ComponentType<ReactRouterLink & { ref?: React.Ref<HTMLAnchorElement>; }> | React.ReactNode; export type ButtonClickEvent = { event: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>; }; export type ButtonOnClick = ((args: ButtonClickEvent) => void) | React.MouseEventHandler<HTMLButtonElement | HTMLAnchorElement> | ((...args: unknown[]) => void); export type ButtonProps = { /** * The content of the button can be a string or a React Element. */ text?: ButtonText; /** * The type HTML attribute. Defaults to `button` to prevent accidental form submissions. */ type?: string; /** * Required if there is no text in the button. If `text` and `children` are undefined, setting the `title` property will automatically set `aria-label` with the same value. */ title?: string; /** * Defines the kind of button. Possible values are `primary`, `secondary` and `tertiary`. Defaults to `primary` (or `secondary` if icon only). */ variant?: ButtonVariant; /** * The size of the button. There is `default`, `small`, `medium` and `large`. The `tertiary` button officially supports only default and large. */ size?: ButtonSize; /** * To be included in the button. [Primary Icons](/icons/primary) can be set as a string (e.g. `icon="chevron_right"`), other icons should be set as React elements. For the `tertiary` button an icon is basically required for accessibility reasons (unless you explicitly turn it off with `icon={false}`). */ icon?: ButtonIcon; /** * Position of icon inside the button. Set to `left` or `right`. Tertiary button variant also supports `top`. Defaults to `right` if not set. */ iconPosition?: ButtonIconPositionAll; /** * Define icon width and height. Defaults to `16px`. */ iconSize?: IconSize; /** * Only for icon buttons. If true, use the style for a selected icon button. Default: `false`. */ selected?: boolean; /** * Provide a string or a React Element to be shown as the tooltip content. */ tooltip?: ButtonTooltip; id?: string; /** * If you want the button to behave as a link. Use with caution! A link should normally visually be a link and not a button. */ href?: string; /** * When button behaves as a link. Used to specify where to open the linked document, specified by `href`. Possible values are `_self`, `_blank`, `_parent` and `_top`. */ target?: string; /** * When button behaves as a link. Used to specify the relationship between a linked resource and the current document. Examples(non-exhaustive list) of values are `nofollow`, `search`, and `tag`. */ rel?: string; /** * Use this property only if you are using a router Link component as the `element` that uses the `to` property to declare the navigation url. */ to?: ButtonTo; /** * If you need to inject completely custom markup (React Element) into the button component. You have then to handle alignment and styling by yourself. */ customContent?: React.ReactNode; /** * If set to `true` the button text will wrap in to new lines if the overflow point is reached. Defaults to `false`. */ wrap?: boolean; /** * Set it to `true` in order to extend the bounding box (above the visual button background). You may also look into the HTML class `dnb-button__bounding` if it needs some CSS customization in order to get the particular button right for your use-case. */ bounding?: boolean; /** * Set it to `true` in order to stretch the button to the available space. Defaults to `false`. */ stretch?: boolean; /** * If set to `true`, an overlaying skeleton with animation will be shown. */ skeleton?: ButtonSkeleton; disabled?: boolean; ref?: React.Ref<HTMLElement>; className?: string; class?: string; children?: ButtonChildren; /** * Only meant to be used for special use cases. Defaults to `button` or `a` depending if href is set or not. */ element?: ButtonElement; onClick?: ButtonOnClick; } & FormStatusBaseProps & Partial<DataAttributes & Omit<Partial<React.HTMLAttributes<HTMLButtonElement | HTMLAnchorElement>>, 'onClick'>> & SpacingProps; /** * The button component should be used as the call-to-action in a form, or as a user interaction mechanism. Generally speaking, a button should not be used when a link would do the trick. Exceptions are made at times when it is used as a navigation element in the action-nav element. */ declare function Button({ ref, ...restProps }: ButtonProps): import("react/jsx-runtime").JSX.Element; declare namespace Button { var getContent: (props: ButtonProps) => any; } export default Button;