1 GitHub star = 1 new component.

Star the repo
Formslayoutgroup

Form Group

Vertical form field grouping with labels and hint text.

Live Preview

Form Group

Usage

Copy and paste this code into your React component:

tsx
import { FormGroupVertical } from 'react-component-kit-ui/forms';

<FormGroupVertical label="Username" forId="u" helpText="Characters only."><input id="u" className="custom-input" /></FormGroupVertical>

Manual Installation

If you are not using the npm package, create a new file and paste the following code: src/components/FormGroupVertical.tsx + FormGroupVertical.css:

FormGroupVertical.tsx
'use client';

import type { ReactNode } from 'react';
import './FormGroupVertical.css';

/** class:list โ†’ className */
function cx(...args: unknown[]): string {
  const out: string[] = [];
  const walk = (v: unknown) => {
    if (!v) return;
    if (typeof v === 'string' || typeof v === 'number') out.push(String(v));
    else if (Array.isArray(v)) v.forEach(walk);
    else if (typeof v === 'object') for (const [k, on] of Object.entries(v as Record<string, unknown>)) if (on) out.push(k);
  };
  args.forEach(walk);
  return out.join(' ');
}

/**
 * FormGroupVertical โ€” A structural wrapper component for grouping an input with its label and validation messaging.
 * 
 * @param {string} label - The descriptive title for the field.
 * @param {string} forId - The target ID of the child input (for label association).
 * @param {string} helpText - Optional secondary guidance text below the input.
 * @param {string} error - Optional error message that applies error styling.
 * @param {boolean} required - Displays a required indicator if true.
 */
export interface FormGroupVerticalProps {
  label: string;
  forId: string;
  helpText?: string;
  error?: string;
  required?: boolean;
  children?: ReactNode;
}

export function FormGroupVertical({ label, forId, helpText, error, required = false,
  children
}: FormGroupVerticalProps) {
  return (
    <>
      <div className={cx(["form-group", { "form-group--error": error }])} data-rk-ec85ff="">
        <div className="form-group__header" data-rk-ec85ff="">
          <label htmlFor={forId} className="form-group__label" data-rk-ec85ff="">
            {label}
            {required && <span className="form-group__req" aria-hidden="true" data-rk-ec85ff="">*</span>}
          </label>
        </div>
        
        <div className="form-group__content" data-rk-ec85ff="">
          {children}
        </div>
        
        {error ? (
          <p className="form-group__error" id={`${forId}-error`} role="alert" data-rk-ec85ff="">{error}</p>
        ) : helpText ? (
          <p className="form-group__help" id={`${forId}-help`} data-rk-ec85ff="">{helpText}</p>
        ) : null}
      </div>
    </>
  );
}

export default FormGroupVertical;
FormGroupVertical.css
/* FormGroupVertical โ€” ported from astro-component-kit (forms/FormGroupVertical.astro) */

.form-group:where([data-rk-ec85ff]) { display: flex; flex-direction: column; gap: var(--sp-2, 0.5rem); width: 100%; margin-bottom: var(--sp-4, 1rem); }

.form-group__label:where([data-rk-ec85ff]) { 
  font-size: 0.8rem; font-weight: 700; 
  color: var(--c-text-1, #e2e8f0); 
  text-transform: uppercase; 
  letter-spacing: 0.05em; 
  margin-left: 0.5rem;
  cursor: pointer;
}

.form-group__req:where([data-rk-ec85ff]) { color: var(--c-error, #f87171); margin-left: 2px; }

.form-group__content:where([data-rk-ec85ff]) { width: 100%; }

.form-group__help:where([data-rk-ec85ff]) { font-size: 0.75rem; color: var(--c-text-2, #64748b); margin: 0 0 0 0.5rem; }

.form-group__error:where([data-rk-ec85ff]) { font-size: 0.75rem; color: var(--c-error, #f87171); font-weight: 600; margin: 0 0 0 0.5rem; }

/* Deep selector to style any input nested inside the group content if it's in an error state */
.form-group--error:where([data-rk-ec85ff]) input, 
.form-group--error:where([data-rk-ec85ff]) textarea, 
.form-group--error:where([data-rk-ec85ff]) select { 
  border-color: var(--c-error, #ef4444) !important; 
  background-color: rgba(239, 68, 68, 0.03) !important;
}

Quick Info

Category
Forms
Filename
FormGroupVertical.tsx
Dependencies
None โ€” pure React + CSS
Tags
layoutgroup