Telepathic/Brooks Forms

May 21, 2026

A reactive graph-based approach to a forms-first component library

You can try the demo out here: Telepathic Forms

The Background Story

Forms are everywhere: every site, every industry, every intake flow. Eventually, it all becomes forms...

Over the years, I've often faced the trouble of implementing a component library into a form-based webpage. Usually, we wanted it spec-driven, wrapped consistently, and dynamically interactive. So what happens is: every developer invents their own spec, their own wrapper style, they lob on top of it React Hook Form (or, if they're smart, TanStackForm), and it quickly becomes a huge mess to debug when things don't work correctly.

Then, you meet a designer or business analyst who wants truly rich form interactions, for instance, where one field dynamically disables and enables the other form fields. Since you're locked into a spec-driven approach, you decide to invent a whole triggering language on top of your spec, and the interactions become complicated immediately. I've seen these grow into entire abstract syntax trees before, just to represent the type of complex form interactions businesses need.

I also noticed that there are limited "fantastic" component libraries for SolidJS. Then, existing form interaction libraries are often very tricky to work with, and they don't ship integrated with a component library for you! They are centralized by nature, and often don't offer fantastic performance if you're not very careful with your implementation.

So, I took it upon myself to build BrooksForms

It's intended to be a component library that's "forms-first", includes the SDUI spec, and lets you spin up pre-defined components with ease. The trigger mechanisms are opinionated, and they provide rich interaction options right out of the gate so you don't need to think about it.

I later renamed it Telepathic Forms once I discovered the graph approach 😁.

"Telepathic Forms treats a form as a reactive graph of field nodes. Each field owns its own runtime state, exposes observable streams, and can react to other fields without forcing every interaction through one central store. The result is a forms-first component system that supports dynamic interactions, generated specs, designer output, and SolidJS-friendly rendering without turning every business rule into a giant centralized trigger DSL."- ChatGPT

The Performance Hit

I often noticed a performance hit with React Hook Form. It would create noticeable flickers, lags, and it was very difficult to integrate triggers with cross-cutting concerns like animations and other nifty micro-interactions. There are solutions, like moving processing to context and further pre-caching and centralizing implementations, but this becomes cumbersome quickly. I figured SolidJS might mitigate these problems, but my initial approach pointed out something concerning:

Did I really want centralized data stores everywhere?

So, after some back and forth with ChatGPT, I realized I could construct something similar to Solid's reactive graph on the form elements as they interacted. I've accomplished this by tying together the actual form elements with Observables. This gave me the ability to have a system where:

One form element updates the other form elements directly, without routing everything through a centralized store.

The first take at this approach was a simple component library that took up 1k lines of code total, only around 60 LOC for the entire triggering mechanism. I was immediately impressed with Codex' output. It worked smooth as butter!

import {distinctUntilChanged, type Observable, Subscription} from "rxjs";
import {FieldRuntimeNode, type NodePatch} from "./FieldRuntimeNode";

type NodeId = string;

export class GraphRuntime {
  private nodes = new Map<NodeId, FieldRuntimeNode<any>>();
  private subs = new Subscription();
  private pendingPatches = new Map<NodeId, NodePatch<any>>();
  private flushScheduled = false;

  hasNode(id: NodeId) {
    return this.nodes.has(id);
  }

  private enqueuePatch(targetId: NodeId, patch: NodePatch<any>) {
    const prev = this.pendingPatches.get(targetId) ?? {};
    this.pendingPatches.set(targetId, {...prev, ...patch});

    if (!this.flushScheduled) {
      this.flushScheduled = true;
      queueMicrotask(() => this.flushPatches());
    }
  }

  private flushPatches() {
    this.flushScheduled = false;

    if (this.pendingPatches.size === 0) return;

    const toApply = Array.from(this.pendingPatches.entries());
    this.pendingPatches.clear();

    toApply.forEach(([id, patch]) => {
      const node = this.nodes.get(id);
      if (!node) return;
      node.applyPatch(patch);
    });
  }

  register<T>(node: FieldRuntimeNode<T>) {
    if (this.nodes.has(node.id)) throw new Error(`Duplicate node id: ${node.id}`);
    this.nodes.set(node.id, node);
    return node;
  }

  get<T>(id: NodeId): FieldRuntimeNode<T> {
    const n = this.nodes.get(id);
    if (!n) throw new Error(`Missing node: ${id}`);
    return n as FieldRuntimeNode<T>;
  }

  wireDisabledWhen(targetId: NodeId, pred$: Observable<boolean>, disabled: boolean) {
    this.subs.add(
      pred$.pipe(distinctUntilChanged()).subscribe((pred) => {
        if (pred) this.enqueuePatch(targetId, {disabledOverride: disabled});
      })
    );
  }

  wireHiddenWhen(targetId: NodeId, pred$: Observable<boolean>, hidden: boolean) {
    this.subs.add(
      pred$.pipe(distinctUntilChanged()).subscribe((pred) => {
        if (pred) this.enqueuePatch(targetId, {hiddenOverride: hidden});
      })
    );
  }

  wireValueWhen(targetId: NodeId, pred$: Observable<boolean>, value: any) {
    this.subs.add(
      pred$.pipe(distinctUntilChanged()).subscribe((pred) => {
        if (pred) this.enqueuePatch(targetId, {value});
      })
    );
  }

  destroy() {
    this.flushPatches();
    this.subs.unsubscribe();
    this.nodes.forEach((n) => {
      n.value$.complete();
      n.touched$.complete();
      n.focused$.complete();
    });
    this.nodes.clear();
  }
}

The Playgrounds + Specs

Inspired by MUI and ShadCN, I decided to completely re-implement the form-relevant components entirely from scratch with SolidJS and Tailwind. I made them 100% configurable via props, and isolated these props into parseable specs. The entire thing is driven through TypeScript, so it's easy to figure out how to write a spec on the fly by hand.

For triggering, I made a few semantic decisions, and I decided to keep the validation functions in place in the object-driven versions of the spec. This simplifies the need for an AST, although, I do like the idea of adding one in the future. For now, you can use objects provided from the server if you really need to (via JSON), and later inject the custom client-side validation functions. That should suffice for most, if not all, use cases.

This made for an incredible vibe-coding session where I drafted an entire trading system form and an entire medical intake form in a matter of seconds with gpt-5.3-codex-spark. I was so happy with these forms, I've included them as demos. They can be easily adapted for compliance as needed. I also made interactive playgrounds for each individual component, so you can play with the props and see what they do.

Update: I've also included a form created from a screenshot of an old pdf form that was for a naturopathic medical intake. This was created in less than a few minutes, directly from the screenshot, proving the simplicity of this approach for digitizing old forms.

The Form Designer Tool

Even with TypeScript, the form’s draftability still wasn’t quite where I wanted it. I really wanted a way to design forms and immediately get usable code output... This is why I created the designer tool!

Designer Tool: TelepathicForms/designer

You can toggle triggers on to see how those work, and play with those fields if you'd like, but it's easiest just to start from scratch. Basically, I'd start by just deleting what's there.

Then, row-by-row, component-by-component, you can add different form elements onto the screen and preview them in real time! It's awesome.

Once you're done, it shows you the code you can copy and paste into your codebase and have an actual, real working form to start with. From there, you can further program in the triggers and validations as needed. There is also limited code-editing functionality directly in the designer tool. Pretty sweet!

The Code

The code is organized around the concept of 'wrappers' for each component. This should let you override styles and functionality easily as needed for branding purposes.

import {createMemo, type Component} from "solid-js";
import type {FieldHandle, FieldSpec} from "../engine/generators";
import Checkbox from "../primitives/Checkbox";
import {fromObservable} from "../utils/fromObservable";

export type CheckboxWrapperProps = {
  spec: FieldSpec;
  field: FieldHandle;
  fullWidth?: boolean;
  inline?: boolean;
};

export const CheckboxWrapper: Component<CheckboxWrapperProps> = (p) => {
  const value = fromObservable(p.field.value$, "");
  const disabled = fromObservable(p.field.disabled$, false);
  const errors = fromObservable(p.field.errors$, []);
  const touched = fromObservable(p.field.touched$, false);

  const checked = createMemo(() => value() === "true");
  const errorText = createMemo(() =>
    disabled() ? "" : touched() ? errors()[0] ?? "" : ""
  );

  return (
    <Checkbox
      id={p.spec.id}
      label={p.spec.label}
      checked={checked()}
      indeterminate={p.spec.indeterminate}
      helperText={p.spec.helperText}
      required={!!p.spec.required}
      disabled={disabled()}
      readOnly={!!p.spec.readOnly}
      fullWidth={p.fullWidth}
      inline={p.inline ?? p.spec.inline}
      size={p.spec.size}
      variant={p.spec.variant}
      ringEnabled={p.spec.ringEnabled}
      animateRingOnFocus={p.spec.animateRingOnFocus}
      ringVariant={p.spec.ringVariant}
      error={!!errorText()}
      errorText={errorText()}
      onChecked={(next) => {
        p.field.setValue(next ? "true" : "");
        p.field.markTouched();
      }}
    />
  );
};

Then, each wrapper wraps around a primitive. They are pretty large, but here's the smallest one:

import {
  Show,
  createEffect,
  createUniqueId,
  mergeProps,
  splitProps,
} from 'solid-js';
import type { JSX } from 'solid-js';

import { cx } from '../utils/cx';
import type { LaserRingVariant } from '../utils/laserRingVariants';
import { useRingAnimation } from '../utils/useRingAnimation';

export type CheckboxSize = 'sm' | 'md' | 'lg';
export type CheckboxVariant = 'outlined' | 'filled' | 'standard';

export type CheckboxProps = Omit<
  JSX.InputHTMLAttributes<HTMLInputElement>,
  'size' | 'type' | 'checked' | 'onChange' | 'onInput'
> & {
  class?: string;
  label?: string;
  helperText?: string;
  error?: boolean;
  errorText?: string;
  required?: boolean;
  disabled?: boolean;
  readOnly?: boolean;
  fullWidth?: boolean;
  inline?: boolean;
  size?: CheckboxSize;
  variant?: CheckboxVariant;

  checked?: boolean;
  indeterminate?: boolean;
  ringEnabled?: boolean;
  animateRingOnFocus?: boolean;
  ringVariant?: LaserRingVariant;
  onRingApi?: (api: {
    pulse: () => void;
    focus: () => void;
    pulseAndFocus: () => void;
  }) => void;

  onChecked?: (checked: boolean, ctx?: { indeterminate?: boolean; event?: Event }) => void;

  renderLabel?: (props: {
    label?: string;
    required?: boolean;
    disabled?: boolean;
    htmlFor?: string;
  }) => JSX.Element;

  renderHelper?: (props: {
    helperText?: string;
    error?: boolean;
    id?: string;
  }) => JSX.Element;

  rootClass?: string;
  labelClass?: string;
  inputClass?: string;
  helperClass?: string;

  inputRef?: (el: HTMLInputElement) => void;
};

const sizeStyles: Record<
  CheckboxSize,
  {
    box: string;
    glyph: string;
    label: string;
    helper: string;
    gap: string;
    helperOffset: string;
  }
> = {
  sm: {
    box: 'h-[18px] w-[18px] rounded-[5px]',
    glyph: 'text-[11px]',
    label: 'text-sm',
    helper: 'text-xs',
    gap: 'gap-2',
    helperOffset: 'pl-6',
  },
  md: {
    box: 'h-[19px] w-[19px] rounded-[6px]',
    glyph: 'text-[12px]',
    label: 'text-sm',
    helper: 'text-xs',
    gap: 'gap-2.5',
    helperOffset: 'pl-7',
  },
  lg: {
    box: 'h-5 w-5 rounded-[7px]',
    glyph: 'text-[13px]',
    label: 'text-base',
    helper: 'text-sm',
    gap: 'gap-3',
    helperOffset: 'pl-8',
  },
};

const variantStyles: Record<CheckboxVariant, string> = {
  outlined: 'bg-white/90 shadow-sm dark:bg-slate-900/60',
  filled:
    'bg-slate-100/90 shadow-inner shadow-slate-200/60 dark:bg-slate-800/60 dark:shadow-slate-900/60',
  standard: 'bg-transparent',
};

const callHandler = <T, E extends Event>(
  handler: JSX.EventHandlerUnion<T, E> | undefined,
  event: E,
) => {
  if (!handler) return;
  const handlers = Array.isArray(handler) ? handler : [handler];
  handlers.forEach((item) => item && item(event));
};

const Checkbox = (props: CheckboxProps) => {
  const merged = mergeProps(props);

  const [local, inputProps] = splitProps(merged, [
    'class', 'label', 'helperText', 'error', 'errorText', 'required', 'disabled', 'readOnly', 'fullWidth', 'inline', 'size', 
    'variant', 'checked', 'indeterminate', 'onChecked', 'renderLabel', 'renderHelper', 'rootClass', 'labelClass', 'inputClass', 'helperClass', 'inputRef',
    'id', 'name', 'value', 'onInput', 'onChange', 'onBlur', 'onKeyDown', 'onFocus', 'ringEnabled', 'animateRingOnFocus', 'ringVariant', 'onRingApi',
  ]);

  let inputEl: HTMLInputElement | undefined;
  let prevChecked: boolean | undefined;

  const required = () => Boolean(local.required);
  const disabled = () => Boolean(local.disabled);
  const readOnly = () => Boolean(local.readOnly);
  const fullWidth = () => Boolean(local.fullWidth);
  const inline = () => Boolean(local.inline);
  const ringEnabled = () => local.ringEnabled ?? true;
  const animateRingOnFocus = () => local.animateRingOnFocus ?? true;

  const size = () => (local.size ?? 'md') as CheckboxSize;
  const variant = () => (local.variant ?? 'outlined') as CheckboxVariant;
  const checked = () => Boolean(local.checked);
  const indeterminate = () => Boolean(local.indeterminate);
  const errorActive = () => Boolean(local.error);
  const {
    ringBox, ringPathD, ringPulseKey, ringActive, ringFadeAnimation, 
    pulseRing, setRingHostEl, setRingMeasureEl, setRingLaserSegEl,
  } = useRingAnimation({
    enabled: ringEnabled,
    radius: () => 8,
    variant: () => local.ringVariant,
  });

  const helperContent = () => {
    if (errorActive()) {
      return local.errorText ?? local.helperText;
    }
    return local.helperText;
  };

  const hasHelper = () => Boolean(local.renderHelper) || Boolean(helperContent());

  const autoId = createUniqueId();
  const inputId = () => local.id ?? `checkbox-${autoId}`;
  const helperId = () => `${inputId()}-helper`;

  const describedBy = () => {
    const ids: string[] = [];
    const fromProps = inputProps['aria-describedby'];

    if (fromProps) ids.push(fromProps);
    if (hasHelper()) ids.push(helperId());

    return ids.length > 0 ? ids.join(' ') : undefined;
  };

  const ariaInvalid = () => (errorActive() ? 'true' : inputProps['aria-invalid']);

  const labelToneClass = () =>
    cx(
      'leading-snug text-slate-700 dark:text-slate-200',
      disabled() ? 'opacity-60' : '',
      readOnly() && !disabled() ? 'opacity-90' : '',
      local.labelClass,
    );

  const helperToneClass = () => {
    if (errorActive()) return 'text-rose-600 dark:text-rose-300';
    return 'text-slate-500 dark:text-slate-400';
  };

  const helperClass = () =>
    cx(sizeStyles[size()].helper, helperToneClass(), 'leading-snug', local.helperClass);

  const boxClass = () => {
    const tone = errorActive()
      ? 'border-rose-500/90 peer-focus:ring-rose-500/40 peer-focus:ring-offset-rose-50 dark:peer-focus:ring-rose-500/50 dark:peer-focus:ring-offset-slate-950'
      : 'border-slate-300/90 peer-focus:ring-emerald-500/35 peer-focus:ring-offset-white dark:border-slate-700 dark:peer-focus:ring-emerald-400/45 dark:peer-focus:ring-offset-slate-950';

    const stateTone = checked() || indeterminate()
      ? errorActive()
        ? 'bg-white text-slate-950 border-rose-500 dark:bg-white dark:text-slate-950 dark:border-rose-400'
        : 'bg-white text-slate-950 border-slate-800/80 dark:bg-white dark:text-slate-950 dark:border-slate-200'
      : 'text-transparent';

    return cx(
      'relative inline-flex shrink-0 select-none items-center justify-center overflow-hidden border transition duration-150 peer-focus:ring-2 peer-focus:ring-offset-1',
      sizeStyles[size()].box,
      variantStyles[variant()],
      tone,
      stateTone,
      disabled() ? 'opacity-60' : '',
      readOnly() && !disabled() ? 'opacity-90' : '',
      local.inputClass,
    );
  };

  const hasLabel = () => Boolean(local.renderLabel) || Boolean(local.label);

  const rootClass = () =>
    cx(
      inline() ? 'flex items-center gap-3' : 'flex flex-col gap-1.5',
      fullWidth() ? 'w-full' : 'inline-flex',
      size() === 'lg' ? 'pt-9' : size() === 'sm' ? 'pt-8' : 'pt-8',
      local.class,
      local.rootClass,
    );

  const controlRowClass = () =>
    cx(
      'min-w-0',
      inline() ? 'flex min-w-0 flex-1 items-center gap-3' : 'flex items-center',
      sizeStyles[size()].gap,
    );

  createEffect(() => {
    const focus = () => inputEl?.focus();
    const pulse = () => pulseRing();
    const pulseAndFocus = () => {
      focus();
      pulse();
    };
    local.onRingApi?.({ pulse, focus, pulseAndFocus });
  });

  const labelContent = () => {
    if (local.renderLabel) {
      return local.renderLabel({
        label: local.label,
        required: required(),
        disabled: disabled(),
        htmlFor: inputId(),
      });
    }

    if (!local.label) return null;

    return (
      <label
        for={inputId()}
        class={cx('min-w-0 break-words', sizeStyles[size()].label, labelToneClass())}
      >
        <span>{local.label}</span>
        <Show when={required()}>
          <span class="text-rose-500"> *</span>
        </Show>
      </label>
    );
  };

  const handleInput: JSX.EventHandlerUnion<HTMLInputElement, InputEvent> = (
    event,
  ) => {
    callHandler(local.onInput, event);
  };

  const handleChange: JSX.EventHandlerUnion<HTMLInputElement, Event> = (event) => {
    const el = event.currentTarget;

    if (disabled() || readOnly()) {
      event.preventDefault();
      el.checked = checked();
      callHandler(local.onChange, event);
      return;
    }

    const nextChecked = el.checked;
    local.onChecked?.(nextChecked, {
      indeterminate: local.indeterminate,
      event,
    });

    callHandler(local.onChange, event);
  };

  createEffect(() => {
    const nextChecked = checked();

    if (prevChecked === undefined) {
      prevChecked = nextChecked;
      return;
    }

    if (nextChecked && !prevChecked) {
      pulseRing();
    }

    prevChecked = nextChecked;
  });

  createEffect(() => {
    if (!inputEl) return;
    inputEl.indeterminate = indeterminate();
  });

  return (
    <div class={rootClass()}>
      <div class={controlRowClass()}>
        <input
          id={inputId()}
          ref={(el) => {
            inputEl = el;
            el.indeterminate = indeterminate();
            local.inputRef?.(el);
          }}
          type="checkbox"
          name={local.name}
          value={local.value}
          checked={checked()}
          required={required()}
          disabled={disabled()}
          aria-readonly={readOnly() ? 'true' : undefined}
          aria-invalid={ariaInvalid()}
          aria-describedby={describedBy()}
          class="peer sr-only"
          onInput={handleInput}
          onChange={handleChange}
          onFocus={(event) => {
            if (animateRingOnFocus()) {
              pulseRing();
            }
            callHandler(local.onFocus, event);
          }}
          onBlur={local.onBlur}
          onKeyDown={local.onKeyDown}
          {...inputProps}
        />

        <div
          class={cx(
            'group relative inline-flex min-w-0 items-start rounded-lg',
            sizeStyles[size()].gap,
            disabled() ? 'cursor-not-allowed' : readOnly() ? 'cursor-default' : 'cursor-pointer',
          )}
        >
          <Show when={ringEnabled()}>
            <span
              ref={setRingHostEl}
              aria-hidden="true"
              class={cx(
                'pointer-events-none absolute -inset-1.5 z-10 opacity-0',
                errorActive()
                  ? 'text-rose-500 dark:text-rose-400'
                  : 'text-emerald-500 dark:text-emerald-400',
              )}
              style={ringActive() ? {animation: ringFadeAnimation()} : undefined}
            >
              <svg
                class="block h-full w-full"
                viewBox={`0 0 ${ringBox().w} ${ringBox().h}`}
                preserveAspectRatio="none"
              >
                <Show when={ringActive()}>
                  {() => (
                    <>
                      <path
                        class="tf-focus-laser-ring-outline"
                        data-pulse={ringPulseKey()}
                        d={ringPathD()}
                        fill="none"
                        vector-effect="non-scaling-stroke"
                        opacity="0.02"
                      />
                      <path
                        ref={setRingMeasureEl}
                        d={ringPathD()}
                        fill="none"
                        stroke="none"
                      />
                      <path
                        ref={setRingLaserSegEl}
                        class="tf-focus-laser-ring-segment"
                        data-pulse={ringPulseKey()}
                        d=""
                        fill="none"
                        stroke="currentColor"
                        stroke-width="2.25"
                        stroke-linecap="round"
                        vector-effect="non-scaling-stroke"
                      />
                    </>
                  )}
                </Show>
              </svg>
            </span>
          </Show>

          <label for={inputId()} class="inline-flex shrink-0 select-none">
            <span class={boxClass()}>
              <span
                aria-hidden="true"
                class={cx(
                  'pointer-events-none absolute inset-0 grid select-none place-items-center font-black leading-none transition-opacity duration-100',
                  sizeStyles[size()].glyph,
                  indeterminate() ? 'opacity-100' : 'opacity-0',
                )}
              ></span>
              <span
                aria-hidden="true"
                class={cx(
                  'pointer-events-none absolute inset-0 grid select-none place-items-center font-black leading-none transition-opacity duration-100',
                  sizeStyles[size()].glyph,
                  checked() && !indeterminate() ? 'opacity-100' : 'opacity-0',
                )}
              ></span>
            </span>
          </label>

          <Show when={hasLabel()}>
            <span class={cx('min-w-0', sizeStyles[size()].label)}>{labelContent()}</span>
          </Show>
        </div>
      </div>

      <Show when={hasHelper()}>
        <div
          id={helperId()}
          class={cx(
            helperClass(),
            inline() ? 'min-w-0 break-words' : sizeStyles[size()].helperOffset,
          )}
        >
          {local.renderHelper
            ? local.renderHelper({
                helperText: helperContent(),
                error: errorActive(),
                id: helperId(),
              })
            : helperContent()}
        </div>
      </Show>
    </div>
  );
};

export default Checkbox;

One note: I do plan to add better dynamic merging of override styles, so stay tuned for that. Otherwise, these should be highly portable.

Each primitive/wrapper combo integrates into the form spec by matching the field kind, selecting the appropriate component, and wiring it into the engine:

switch (f.kind) {
    case FieldKind.dateRange: 
        return <DateRangePickerWrapper spec={f} field={handle} fullWidth={p.fullWidth} />;
    case FieldKind.date: 
        return <DatePickerWrapper spec={f} field={handle} fullWidth={p.fullWidth} />;
    case FieldKind.textArea: 
        return <TextAreaWrapper spec={f} field={handle} fullWidth={p.fullWidth} />;
    case FieldKind.phone: 
        return <PhoneWrapper spec={f} field={handle} fullWidth={p.fullWidth} />;
    case FieldKind.number: 
        return <NumberWrapper spec={f} field={handle} fullWidth={p.fullWidth} />;
    case FieldKind.currency: 
        return <CurrencyWrapper spec={f} field={handle} fullWidth={p.fullWidth} />;
    case FieldKind.percent: 
        return <PercentWrapper spec={f} field={handle} fullWidth={p.fullWidth} />;
    case FieldKind.select: 
        return <SelectWrapper spec={f} field={handle} fullWidth={p.fullWidth} />;
    case FieldKind.multiSelect: 
        return <MultiSelectWrapper spec={f} field={handle} fullWidth={p.fullWidth} />;
    case FieldKind.checkbox: 
        return <CheckboxWrapper spec={f} field={handle} fullWidth={p.fullWidth} />;
    case FieldKind.inlineCheckbox: 
        return <CheckboxWrapper spec={f} field={handle} fullWidth={p.fullWidth} inline={true} />;
    case FieldKind.switch: 
        return <SwitchWrapper spec={f} field={handle} fullWidth={p.fullWidth} />;
    case FieldKind.radio: 
        return <RadioGroupWrapper spec={f} field={handle} fullWidth={p.fullWidth} />;
    case FieldKind.inlineRadio: 
        return <RadioGroupWrapper spec={f} field={handle} fullWidth={p.fullWidth} inline={true} />;
    case FieldKind.ssn: 
        return <SsnWrapper spec={f} field={handle} fullWidth={p.fullWidth} />;
    case FieldKind.zip: 
        return <ZipWrapper spec={f} field={handle} fullWidth={p.fullWidth} />;
    case FieldKind.slider: 
        return <SliderWrapper spec={f} field={handle} fullWidth={p.fullWidth} />;
    case FieldKind.time: 
        return <TimePickerWrapper spec={f} field={handle} fullWidth={p.fullWidth} />;
    case FieldKind.password: 
        return <PasswordWrapper spec={f} field={handle} fullWidth={p.fullWidth} />;
    case FieldKind.text: default:
        return <TextFieldWrapper spec={f} field={handle} fullWidth={p.fullWidth} />;
}

In Conclusion

I haven't quite gotten this production-ready... yet... so I haven't released a library... yet... but I plan to have it work with an opt-in approach similar to ShadCN where you can optionally pull in the components you need and edit them in your own codebase stylistically. I really like that idea, and hopefully, I've designed this code idempotently enough for that to be possible.

I've included themes and different light/dark variations, some sweet animations, and some other cool features as well. If you'd like to see the source code, simply reach out to me at bdubois2@gmail.com and I can help you set it up in your codebase. Should save you a ton of time and headache!

So there you have it: a forms-first component library... with an SDUI approach baked directly into it... created by yours truly,

- Brooks DuBois

© 2026Brooks DuBois™