Files
modeling-app/src/components/ActionButton.tsx
Jess Frazelle d168ef94e9 Sort imports (#6101)
* add package.json

Signed-off-by: Jess Frazelle <github@jessfraz.com>

initial run;

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

more fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

clientsidescne

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

paths

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

fix styles

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

combine

Signed-off-by: Jess Frazelle <github@jessfraz.com>

eslint rule

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

my ocd

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

constants file

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

no more import sceneInfra

Signed-off-by: Jess Frazelle <github@jessfraz.com>

updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

try fix circular import

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-02 06:54:26 +00:00

149 lines
4.2 KiB
TypeScript

import type { ForwardedRef } from 'react'
import React, { forwardRef } from 'react'
import type { LinkProps } from 'react-router-dom'
import { Link } from 'react-router-dom'
import type { ActionIconProps } from '@src/components/ActionIcon'
import { ActionIcon } from '@src/components/ActionIcon'
import { openExternalBrowserIfDesktop } from '@src/lib/openWindow'
import { PATHS } from '@src/lib/paths'
interface BaseActionButtonProps {
iconStart?: ActionIconProps
iconEnd?: ActionIconProps
className?: string
}
type ActionButtonAsButton = BaseActionButtonProps &
Omit<
React.ButtonHTMLAttributes<HTMLButtonElement>,
keyof BaseActionButtonProps
> & {
Element: 'button'
}
type ActionButtonAsLink = BaseActionButtonProps &
Omit<LinkProps, keyof BaseActionButtonProps> & {
Element: 'link'
}
type ActionButtonAsExternal = BaseActionButtonProps &
Omit<LinkProps, keyof BaseActionButtonProps> & {
Element: 'externalLink'
}
type ActionButtonAsElement = BaseActionButtonProps &
Omit<React.HTMLAttributes<HTMLElement>, keyof BaseActionButtonProps> & {
Element: React.ComponentType<React.HTMLAttributes<HTMLButtonElement>>
}
export type ActionButtonProps =
| ActionButtonAsButton
| ActionButtonAsLink
| ActionButtonAsExternal
| ActionButtonAsElement
export const ActionButton = forwardRef((props: ActionButtonProps, ref) => {
const classNames = `action-button p-0 m-0 group mono text-xs leading-none flex items-center gap-2 rounded-sm border-solid border border-chalkboard-30 hover:border-chalkboard-40 enabled:dark:border-chalkboard-70 dark:hover:border-chalkboard-60 dark:bg-chalkboard-90/50 text-chalkboard-100 dark:text-chalkboard-10 ${
props.iconStart
? props.iconEnd
? 'px-0' // No padding if both icons are present
: 'pr-2' // Padding on the right if only the start icon is present
: props.iconEnd
? 'pl-2' // Padding on the left if only the end icon is present
: 'px-2' // Padding on both sides if no icons are present
} ${props.className ? props.className : ''}`
switch (props.Element) {
case 'button': {
// Note we have to destructure 'className' and 'Element' out of props
// because we don't want to pass them to the button element;
// the same is true for the other cases below.
const {
Element,
iconStart,
iconEnd,
children,
className: _className,
...rest
} = props
return (
<button
ref={ref as ForwardedRef<HTMLButtonElement>}
className={classNames}
{...rest}
>
{iconStart && <ActionIcon {...iconStart} />}
{children}
{iconEnd && <ActionIcon {...iconEnd} />}
</button>
)
}
case 'link': {
const {
Element,
to,
iconStart,
iconEnd,
children,
className: _className,
...rest
} = props
return (
<Link
ref={ref as ForwardedRef<HTMLAnchorElement>}
to={to || PATHS.INDEX}
className={classNames}
{...rest}
>
{iconStart && <ActionIcon {...iconStart} />}
{children}
{iconEnd && <ActionIcon {...iconEnd} />}
</Link>
)
}
case 'externalLink': {
const {
Element,
to,
iconStart,
iconEnd,
children,
className: _className,
...rest
} = props
return (
<Link
ref={ref as ForwardedRef<HTMLAnchorElement>}
to={to || PATHS.INDEX}
className={classNames}
onClick={openExternalBrowserIfDesktop(to as string)}
{...rest}
target="_blank"
>
{iconStart && <ActionIcon {...iconStart} />}
{children}
{iconEnd && <ActionIcon {...iconEnd} />}
</Link>
)
}
default: {
const {
Element,
iconStart,
children,
className: _className,
...rest
} = props
return (
<Element className={classNames} {...rest}>
{props.iconStart && <ActionIcon {...props.iconStart} />}
{children}
{props.iconEnd && <ActionIcon {...props.iconEnd} />}
</Element>
)
}
}
})