Functional Weave
Code in Python

react.form.button@1.0.1

impl/typescript.tsx

1,511 bytes · the TypeScript implementation · view raw

"use client";

import type { JSX, MouseEvent, ReactNode } from "react";
import type { ButtonProps } from "./react_form_button_types.ts";

function present(node: ReactNode): boolean {
  return node !== null && node !== undefined && node !== false && node !== "";
}

/**
 * The GOV.UK button. While loading it stays enabled, so it keeps focus and a
 * screen reader still finds it, but it says aria-disabled="true" and a press
 * is swallowed, form submission included: the second click of a double click
 * sends nothing twice. disabled is the real attribute, with aria-disabled as
 * GOV.UK renders it.
 */
export function Button(props: ButtonProps): JSX.Element {
  const { children, id, name, value, disabled, loading, loadingText, onClick, className } = props;
  const variant = props.variant ?? "primary";
  const classes = [
    "fune-button",
    variant === "primary" ? null : `fune-button--${variant}`,
    loading ? "fune-button--loading" : null,
    className || null,
  ]
    .filter(Boolean)
    .join(" ");
  function press(event: MouseEvent<HTMLButtonElement>): void {
    if (loading) {
      event.preventDefault();
      return;
    }
    onClick?.();
  }
  return (
    <button
      className={classes}
      id={id}
      type={props.type ?? "submit"}
      name={name}
      value={value}
      disabled={disabled}
      aria-disabled={disabled || loading ? true : undefined}
      onClick={press}
    >
      {loading && present(loadingText) ? loadingText : children}
    </button>
  );
}