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