bottega

sections

Gradient Border Contact Form

A dark contact / feedback form card whose border is painted with a vivid diagonal purple-to-cyan gradient using the CSS padding-box + border-box background layering trick — two background declarations share the same rule, the first (padding-box) floods the card with var(--background) while the second (border-box) paints the gradient across the full box so only the exposed 2px border strip shows color. The form contains a labeled email input, a labeled message textarea, and a ghost submit button that transitions to a filled primary state on hover. All interactive states — input focus, button focus, button hover — use Bottega contract tokens; focus-visible rings are delivered via var(--ring). No JavaScript, fully server-renderable, keyboard-operable, and compatible with any shadcn theme.

Ported from gharsh11032000 (MIT)

Get in touch


Install

1. Register the namespace (once per project):

json
// components.json — register the @bottega namespace once
{
  "registries": {
    "@bottega": { "url": "https://bottega.ariacode.ca/r/{name}.json" }
  }
}

2. Add the component:

bash
npx shadcn add @bottega/gradient-border-contact-form

Usage

Usagetsx
<GradientBorderContactForm />

Props

PropTypeDefaultDescription
headingstringHeading shown above the form.
emailLabelstringCompany EmailLabel for the email / company-email field.
emailPlaceholderstringPlaceholder for the email input.
messageLabelstringHow Can We Help You?Label for the message textarea.
messagePlaceholderstringPlaceholder for the message textarea.
submitLabelstringSubmitLabel on the submit button.
onSubmit(data: { email: string; message: string; }) => voidCalled when the form is submitted with the field values.
classNamestringAdditional class names merged onto the root wrapper.

Source

gradient-border-contact-form.tsxtsx
import type React from "react";
import styles from "./gradient-border-contact-form.module.css";

export type GradientBorderContactFormProps = {
  /** Heading shown above the form. */
  heading?: string;
  /** Label for the email / company-email field. */
  emailLabel?: string;
  /** Placeholder for the email input. */
  emailPlaceholder?: string;
  /** Label for the message textarea. */
  messageLabel?: string;
  /** Placeholder for the message textarea. */
  messagePlaceholder?: string;
  /** Label on the submit button. */
  submitLabel?: string;
  /** Called when the form is submitted with the field values. */
  onSubmit?: (data: { email: string; message: string }) => void;
  /** Additional class names merged onto the root wrapper. */
  className?: string;
};

/**
 * Gradient-border contact form.
 *
 * A dark contact/feedback form whose card container uses the
 * CSS `padding-box` + `border-box` background trick to paint a
 * vivid diagonal gradient (purple → cyan via `--primary` and `--accent`)
 * only on the 2px border while the fill stays `--background`.
 * Inputs and textarea use a subtle token-based border that highlights
 * with `--primary` on focus-visible. The submit button slides from a
 * muted ghost state to a filled `--primary-foreground` / `--primary`
 * appearance on hover. All interactive states use `:focus-visible`
 * rings via `var(--ring)`. No JS — purely static CSS with a real
 * `<form>` and server-renderable markup.
 */
export function GradientBorderContactForm({
  heading,
  emailLabel = "Company Email",
  emailPlaceholder,
  messageLabel = "How Can We Help You?",
  messagePlaceholder,
  submitLabel = "Submit",
  onSubmit,
  className = "",
}: GradientBorderContactFormProps) {
  function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    if (!onSubmit) return;
    const fd = new FormData(e.currentTarget);
    onSubmit({
      email: (fd.get("email") as string) ?? "",
      message: (fd.get("message") as string) ?? "",
    });
  }

  return (
    <div className={[styles.container, className].filter(Boolean).join(" ")}>
      {heading && <p className={styles.heading}>{heading}</p>}
      <form className={styles.form} onSubmit={handleSubmit} noValidate>
        <div className={styles.group}>
          <label htmlFor="gbcf-email" className={styles.label}>
            {emailLabel}
          </label>
          <input
            type="email"
            id="gbcf-email"
            name="email"
            className={styles.input}
            placeholder={emailPlaceholder}
            required
            autoComplete="email"
          />
        </div>

        <div className={styles.group}>
          <label htmlFor="gbcf-message" className={styles.label}>
            {messageLabel}
          </label>
          <textarea
            id="gbcf-message"
            name="message"
            className={styles.textarea}
            placeholder={messagePlaceholder}
            required
            rows={5}
          />
        </div>

        <button type="submit" className={styles.submitBtn}>
          {submitLabel}
        </button>
      </form>
    </div>
  );
}

Dependencies

  • @bottega/tokens