sendou.ink/app/components/Button.tsx
Kalle b4cc185d1d
Some checks are pending
Tests and checks on push / run-checks-and-tests (push) Waiting to run
Updates translation progress / update-translation-progress-issue (push) Waiting to run
Scrims (#2211)
* Initial

* Progress

* Initial UI

* Can submit request

* Progress

* Show text if no scrims

* Can cancel request, tabs

* Delete post

* Popover if can't delete

* Request rows

* Progress

* Scrim page initial

* Fix migration order

* Progress

* Progress

* Works again

* Make it compile

* Make it compile again

* Work

* Progress

* Progress

* Progress

* Associations initial

* Association visibility work

* notFoundVisibility form fields initial

* Progress

* Association leave/join + reset invite code

* Progress

* Select test

* Merge branch 'rewrite' into scrims

* Remeda for groupBy

* Select with search

* Outline styling for select

* Select done?

* Fix prop names

* Paginated badges

* Less important

* Select no results

* Handle limiting select width

* UserSearch non-working

* Fix problem from merge

* Remove UserSearch for now

* Remove todo

* Flaggable

* Remove TODOs

* i18n start + styling

* Progress

* i18n done

* Add association e2e test

* E2E tests

* Done?

* Couple leftovers
2025-04-20 22:51:23 +03:00

139 lines
2.6 KiB
TypeScript

import { Link } from "@remix-run/react";
import type { LinkProps } from "@remix-run/react";
import clsx from "clsx";
import * as React from "react";
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?:
| "primary"
| "success"
| "outlined"
| "outlined-success"
| "destructive"
| "minimal"
| "minimal-success"
| "minimal-destructive";
size?: "miniscule" | "tiny" | "big";
loading?: boolean;
loadingText?: string;
icon?: JSX.Element;
testId?: string;
_ref?: React.LegacyRef<HTMLButtonElement> | React.ForwardedRef<unknown>;
}
export function Button(props: ButtonProps) {
const {
variant,
loading,
children,
loadingText,
size,
className,
icon,
type = "button",
testId,
_ref,
...rest
} = props;
return (
<button
className={clsx(
"button",
variant,
{
"disabled-opaque": props.disabled,
loading,
tiny: size === "tiny",
big: size === "big",
miniscule: size === "miniscule",
},
className,
)}
disabled={props.disabled || loading}
type={type}
data-testid={testId}
ref={props._ref as React.LegacyRef<HTMLButtonElement>}
{...rest}
>
{icon &&
React.cloneElement(icon, {
className: clsx("button-icon", { lonely: !children }),
title: rest.title,
})}
{loading && loadingText ? loadingText : children}
</button>
);
}
type LinkButtonProps = Pick<
ButtonProps,
"variant" | "children" | "className" | "size" | "testId" | "icon"
> &
Pick<LinkProps, "to" | "prefetch" | "preventScrollReset"> & {
"data-cy"?: string;
isExternal?: boolean;
onClick?: () => void;
};
export function LinkButton({
variant,
children,
size,
className,
to,
prefetch,
isExternal,
testId,
icon,
preventScrollReset,
onClick,
}: LinkButtonProps) {
if (isExternal) {
return (
<a
className={clsx(
"button",
variant,
{ tiny: size === "tiny", big: size === "big" },
className,
)}
href={to as string}
data-testid={testId}
target="_blank"
rel="noreferrer"
onClick={onClick}
>
{icon &&
React.cloneElement(icon, {
className: clsx("button-icon", {
lonely: !children,
}),
})}
{children}
</a>
);
}
return (
<Link
className={clsx(
"button",
variant,
{ tiny: size === "tiny", big: size === "big" },
className,
)}
to={to}
data-testid={testId}
prefetch={prefetch}
preventScrollReset={preventScrollReset}
>
{icon &&
React.cloneElement(icon, {
className: clsx("button-icon", { lonely: !children }),
})}
{children}
</Link>
);
}