|
|
@@ -7,46 +7,39 @@ import { Button } from '@tesseract-design/web-base'; |
|
|
|
*/ |
|
|
|
export type LinkButtonDerivedElement = HTMLAnchorElement; |
|
|
|
|
|
|
|
/** |
|
|
|
* Props of the {@link LinkButton} component. |
|
|
|
*/ |
|
|
|
export interface LinkButtonProps<T = any> extends Omit<React.HTMLProps<LinkButtonDerivedElement>, 'href' | 'size'> { |
|
|
|
/** |
|
|
|
* Should the component occupy the whole width of its parent? |
|
|
|
*/ |
|
|
|
block?: boolean; |
|
|
|
/** |
|
|
|
* Variant of the component. |
|
|
|
*/ |
|
|
|
variant?: Button.Variant; |
|
|
|
/** |
|
|
|
* Complementary content of the component. |
|
|
|
*/ |
|
|
|
subtext?: React.ReactNode; |
|
|
|
/** |
|
|
|
* Short complementary content displayed at the edge of the component. |
|
|
|
*/ |
|
|
|
badge?: React.ReactNode; |
|
|
|
/** |
|
|
|
* Is this component part of a menu? |
|
|
|
*/ |
|
|
|
menuItem?: boolean; |
|
|
|
/** |
|
|
|
* Size of the component. |
|
|
|
*/ |
|
|
|
size?: Button.Size; |
|
|
|
/** |
|
|
|
* Should the component's content use minimal space? |
|
|
|
*/ |
|
|
|
compact?: boolean; |
|
|
|
/** |
|
|
|
* Component to use in rendering. |
|
|
|
*/ |
|
|
|
component?: React.ElementType<T>; |
|
|
|
/** |
|
|
|
* Is the component unable to receive activation? |
|
|
|
*/ |
|
|
|
disabled?: boolean; |
|
|
|
interface LinkButtonCommonProps extends Omit<React.HTMLProps<LinkButtonDerivedElement>, 'href' | 'size'> { |
|
|
|
/** |
|
|
|
* Should the component occupy the whole width of its parent? |
|
|
|
*/ |
|
|
|
block?: boolean; |
|
|
|
/** |
|
|
|
* Variant of the component. |
|
|
|
*/ |
|
|
|
variant?: Button.Variant; |
|
|
|
/** |
|
|
|
* Complementary content of the component. |
|
|
|
*/ |
|
|
|
subtext?: React.ReactNode; |
|
|
|
/** |
|
|
|
* Short complementary content displayed at the edge of the component. |
|
|
|
*/ |
|
|
|
badge?: React.ReactNode; |
|
|
|
/** |
|
|
|
* Is this component part of a menu? |
|
|
|
*/ |
|
|
|
menuItem?: boolean; |
|
|
|
/** |
|
|
|
* Size of the component. |
|
|
|
*/ |
|
|
|
size?: Button.Size; |
|
|
|
/** |
|
|
|
* Should the component's content use minimal space? |
|
|
|
*/ |
|
|
|
compact?: boolean; |
|
|
|
/** |
|
|
|
* Is the component unable to receive activation? |
|
|
|
*/ |
|
|
|
disabled?: boolean; |
|
|
|
/** |
|
|
|
* Graphical representation of the component. |
|
|
|
*/ |
|
|
@@ -55,12 +48,36 @@ export interface LinkButtonProps<T = any> extends Omit<React.HTMLProps<LinkButto |
|
|
|
* Should the graphical representation of the component be placed after the children? |
|
|
|
*/ |
|
|
|
iconAfterChildren?: boolean; |
|
|
|
/** |
|
|
|
* URL to navigate to. |
|
|
|
*/ |
|
|
|
href?: string | unknown; |
|
|
|
} |
|
|
|
|
|
|
|
interface LinkButtonAnchorProps extends Pick<React.HTMLProps<LinkButtonDerivedElement>, 'href'> { |
|
|
|
component: 'a'; |
|
|
|
} |
|
|
|
|
|
|
|
interface LinkButtonComponentType { |
|
|
|
(props: { href?: string }): React.ReactNode; |
|
|
|
} |
|
|
|
|
|
|
|
interface LinkButtonFCProps< |
|
|
|
C extends LinkButtonComponentType = LinkButtonComponentType |
|
|
|
> { |
|
|
|
component: C; |
|
|
|
href: C extends (props: { href?: infer Href }) => React.ReactNode ? Href : never; |
|
|
|
} |
|
|
|
|
|
|
|
type LinkButtonAllProps< |
|
|
|
T extends LinkButtonComponentType = LinkButtonComponentType |
|
|
|
> = |
|
|
|
LinkButtonAnchorProps | LinkButtonFCProps<T>; |
|
|
|
|
|
|
|
/** |
|
|
|
* Props of the {@link LinkButton} component. |
|
|
|
*/ |
|
|
|
export type LinkButtonProps< |
|
|
|
T extends LinkButtonComponentType = LinkButtonComponentType |
|
|
|
> = |
|
|
|
LinkButtonCommonProps & LinkButtonAllProps<T>; |
|
|
|
|
|
|
|
/** |
|
|
|
* Component for performing a navigation action. |
|
|
|
*/ |
|
|
@@ -75,7 +92,7 @@ export const LinkButton = React.forwardRef<LinkButtonDerivedElement, LinkButtonP |
|
|
|
compact = false, |
|
|
|
className, |
|
|
|
block = false, |
|
|
|
component: EnabledComponent = 'a', |
|
|
|
component: EnabledComponent = 'a' as const, |
|
|
|
disabled = false, |
|
|
|
href, |
|
|
|
style, |
|
|
@@ -85,14 +102,18 @@ export const LinkButton = React.forwardRef<LinkButtonDerivedElement, LinkButtonP |
|
|
|
}, |
|
|
|
forwardedRef, |
|
|
|
) => { |
|
|
|
const Component = disabled ? 'button' : EnabledComponent; |
|
|
|
const Component = (disabled ? 'button' : EnabledComponent) as 'a'; |
|
|
|
const extraProps = { |
|
|
|
disabled: disabled || undefined, |
|
|
|
}; |
|
|
|
|
|
|
|
return ( |
|
|
|
<Component |
|
|
|
{...etcProps} |
|
|
|
href={disabled ? undefined : href} |
|
|
|
{...extraProps} |
|
|
|
href={disabled ? undefined : href as string} |
|
|
|
type={disabled ? 'button' : undefined} |
|
|
|
ref={forwardedRef} |
|
|
|
disabled={disabled || undefined} |
|
|
|
className={clsx( |
|
|
|
'items-center justify-center rounded overflow-hidden ring-secondary/50 leading-none select-none no-underline m-0', |
|
|
|
'focus:outline-0 focus:ring-4', |
|
|
@@ -205,16 +226,34 @@ export const LinkButton = React.forwardRef<LinkButtonDerivedElement, LinkButtonP |
|
|
|
LinkButton.displayName = 'LinkButton'; |
|
|
|
|
|
|
|
LinkButton.defaultProps = { |
|
|
|
variant: 'bare', |
|
|
|
size: 'medium', |
|
|
|
compact: false, |
|
|
|
menuItem: false, |
|
|
|
component: 'a', |
|
|
|
variant: 'bare' as const, |
|
|
|
size: 'medium' as const, |
|
|
|
compact: false as const, |
|
|
|
menuItem: false as const, |
|
|
|
badge: undefined, |
|
|
|
subtext: undefined, |
|
|
|
block: false, |
|
|
|
disabled: false, |
|
|
|
block: false as const, |
|
|
|
disabled: false as const, |
|
|
|
icon: undefined, |
|
|
|
iconAfterChildren: false as const, |
|
|
|
// eslint-disable-next-line react/default-props-match-prop-types |
|
|
|
component: 'a' as const, |
|
|
|
// eslint-disable-next-line react/default-props-match-prop-types |
|
|
|
href: undefined, |
|
|
|
}; |
|
|
|
|
|
|
|
// extend the component type here for defining new props |
|
|
|
// interface LinkButtonComponentType { |
|
|
|
// (props: { href?: number }): React.ReactNode; |
|
|
|
// } |
|
|
|
|
|
|
|
// const CustomLink = (props: { href?: string | number }) => { |
|
|
|
// return null; |
|
|
|
// }; |
|
|
|
// |
|
|
|
// const a = ( |
|
|
|
// <LinkButton |
|
|
|
// component="a" |
|
|
|
// href="string" |
|
|
|
// /> |
|
|
|
// ); |