npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@designdaddy/form

v0.1.1

Published

Design Daddy form — attribute-driven fields, validation, and layout

Downloads

30

Readme

@designdaddy/form

Attribute-driven React form. Pass field config via props — the package ships no labels, options, or sample data.

Styles are built in — import Form only. No theme package and no separate CSS import required. The form wraps itself in .fds-root with its own tokens. Theme it with theme / className / style props (same idea as @designdaddy/datagrid).

109 unique field types (+ aliases), documented by category in the docs UI.


Table of contents

  1. Install
  2. Quick start
  3. What to use (Form vs pieces)
  4. Field types by category
  5. Field attributes
  6. Styled controls
  7. Form props by feature
  8. Steps, review, and draft
  9. Styling
  10. Exports
  11. Local pack / publish
  12. Run the docs UI

Install

npm install @designdaddy/form

Peer dependency: React 17+ (18 / 19 supported).

In this monorepo:

cd designdaddy
npm install

Quick start

import { Form } from "@designdaddy/form";

const fields = [
  { id: "email", type: "email", label: "Email", required: true, autoComplete: "email" },
  { id: "password", type: "password", label: "Password", required: true, strengthIndicator: true },
  {
    type: "section",
    id: "prefs",
    title: "Preferences",
    columns: 2,
    fields: [
      {
        id: "role",
        type: "select",
        label: "Role",
        options: [
          { value: "designer", label: "Designer" },
          { value: "developer", label: "Developer" },
        ],
      },
    ],
  },
];

export default function SignupForm() {
  return (
    <Form
      fields={fields}
      className="my-form"
      theme={{ primary: "#0f766e", radius: "10px" }}
      submitLabel="Save"
      resetLabel="Reset"
      onSubmit={(values) => console.log(values)}
    />
  );
}

No extra CSS import — styles load with Form.


What to use (Form vs pieces)

| Need | Use | |------|-----| | Full form (fields + validation + actions + theme) | Form | | Custom layout / wizard chrome | FormShell + FormSection + FormField | | Step indicator only | FormSteps | | Button row only | FormActions | | Map a type → control | FieldRenderer / FIELD_REGISTRY | | Validation / theme helpers (no UI) | validateFields, buildInitialValues, themeToCssVars, … |


Field types by category

Use type on each field. Aliases: telephone→tel, datetime→datetime-local, zip→postal, swift→ifsc.

| Category | Count | Types | |----------|------:|-------| | Native / HTML | 33 | text, password, email, search, tel, url, number, range, date, time, datetime-local, month, week, color, checkbox, radio, file, hidden, submit, reset, button, image, textarea, select, multiselect, optgroup, datalist, postal, username, progress, meter, output | | Selection | 14 | toggle, searchable-select, autocomplete, combobox, dependent-select, tree-select, dual-list, transfer-list, sortable-list, card-select, image-select, icon-select, lookup, mention | | Media | 10 | signature, image-upload, avatar-upload, camera, audio-recorder, audio-upload, video-recorder, video-upload, qr-scanner, barcode-scanner | | Values & design | 19 | otp, pin, tags, chips, rating, currency, percentage, measurement, duration, timezone, language, country, state, city, font, icon, emoji, color-palette, gradient | | Location | 3 | gps, map-picker, address-search | | Payments | 6 | credit-card, cvv, expiry, upi, bank-account, ifsc | | Security / bio | 7 | captcha, security-question, security-answer, fingerprint, face, iris, voice | | Structure | 2 | repeater, matrix | | Scheduling | 3 | appointment, calendar, time-slot | | Editors & AI | 8 | richtext, code, json, sql, markdown, xml-yaml, ai-prompt, ai-autocomplete | | Consent | 3 | terms, privacy, cookie | | Layout | 1 | section (groups nested fields; not an input) | | Total | 109 | |

Docs split each category into pages of up to 5 types, each with demo + props + styling.


Field attributes

| Attribute | Purpose | |-----------|---------| | id | Value key (required for inputs) | | type | Control type | | label | Visible label (you supply it) | | required / requiredMessage | Required + * | | optional / optionalLabel / markOptional | Mark optional | | placeholder | Empty-state text inside the control | | help / tooltip | Hint below field / extra tip | | defaultValue | Initial value | | disabled / readOnly / hidden | State | | visibleWhen | { field, equals } or function | | validate / pattern / min / max / minLength / maxLength | Validation | | validateOn | blur | change (per field) | | mask | 0 digit, A letter, * alnum | | size / fullWidth / width | sm | md | lg, full grid span, CSS width | | labelPosition | above | beside | | autoComplete / ariaLabel / name / htmlId | A11y / browser attrs | | options / optionsMap / getOptions | Choices / cascading | | characterCounter | With maxLength on textarea | | className / inputClassName | Extra classes on wrapper / input | | section fields | title, description, columns, collapsible, fields[] |

Type-specific attributes (e.g. minuteStep, chooseLabel, dependsOn, length) are listed on each field page in the docs.


Styled controls

Several native-looking types render as custom UI. Pass native: true on select or file for the browser default.

Date & time

date, time, datetime-local, month, and week use popover pickers.

{
  id: "startsAt",
  type: "datetime-local",
  label: "Starts at",
  placeholder: "Select date & time",
  minuteStep: 1,
  minYear: 1950,
  maxYear: 2035,
  todayLabel: "Today",
  clearLabel: "Clear",
  locale: "en-IN",
}

Emoji

{
  id: "reaction",
  type: "emoji",
  label: "Emoji",
  ariaLabel: "Choose emoji",
  options: ["😀", "😃", "👍", "❤️", "🎉"],
  columns: 8,
}

File upload

{
  id: "resume",
  type: "file",
  label: "Resume",
  accept: ".pdf,.doc",
  chooseLabel: "Browse files",
  dragHint: "or drag and drop here",
}

Form props by feature

Data and values

| Prop | Purpose | |------|---------| | fields | Field / section config | | values / defaultValues | Controlled or uncontrolled | | onChange / onValuesChange | Value callbacks |

Validation

| Prop | Purpose | |------|---------| | errors | Controlled errors map | | validateOn | blur (default) | change | | beforeSubmit | async guard; return false to cancel |

Actions

| Prop | Purpose | |------|---------| | onSubmit / onReset / onDraftSave | Actions | | submitLabel / resetLabel / draftLabel | Button copy (omit = hide that button) | | showActions | Show default action row (default true) | | renderActions | Custom action slot |

Steps and review

| Prop | Purpose | |------|---------| | steps | [{ id, label, fieldIds }] — or fields: ["id", …] shorthand | | currentStep / onStepChange | Controlled step | | review / onReview | Review screen before submit | | confirmMessage | Confirm dialog before submit |

Layout and state

| Prop | Purpose | |------|---------| | columns | Default section columns | | labelPosition | Default label layout (above | beside) | | loading / disabled / readOnly | Form-wide state |

Styling (like Data Grid)

| Prop | Purpose | |------|---------| | className | Extra class on .fds-root | | style | Inline styles / CSS variables | | theme | Design tokens → CSS variables (see Styling) |

Form element

| Prop | Purpose | |------|---------| | id / name / method / action | Native form attrs | | autoComplete / noValidate | Browser form behavior (noValidate default true) |


Steps, review, and draft

<Form
  fields={allFields}
  steps={[
    { id: "account", label: "Account", fieldIds: ["email", "password"] },
    { id: "profile", label: "Profile", fieldIds: ["name", "role"] },
  ]}
  review
  draftLabel="Save draft"
  submitLabel="Finish"
  onDraftSave={console.log}
  onSubmit={console.log}
/>

fieldIds filters the top-level fields list. You can also pass fields: ["email", "password"] as a shorthand for the same thing.


Styling

Control appearance with props — same pattern as Data Grid.

<Form
  className="my-form"
  theme={{
    primary: "#0f766e",
    primaryDark: "#115e59",
    primarySoft: "rgba(15, 118, 110, 0.14)",
    border: "#99f6e4",
    borderStrong: "#5eead4",
    text: "#042f2e",
    muted: "#0f766e",
    background: "#ecfdf5",
    surface: "#ccfbf1",
    panel: "#ffffff",
    radius: "12px",
    controlHeight: "2.5rem",
  }}
  style={{ "--fds-gap": "1.1rem", "--fds-text-md": "13px" }}
  fields={fields}
  submitLabel="Save"
  onSubmit={console.log}
/>
/* Import AFTER Form so overrides win */
.my-form .fds-btn--primary {
  letter-spacing: 0.02em;
}

.my-form .fds-field__label {
  text-transform: uppercase;
  font-size: 11px;
}

Theme keys → CSS variables

| theme key | CSS variable | |-----------|----------------| | primary | --fds-teal | | primaryDark | --fds-teal-dark | | primarySoft | --fds-teal-soft | | border / borderStrong | --fds-border / --fds-border-strong | | text / muted | --fds-text / --fds-muted | | danger / success | --fds-danger / --fds-success | | background / surface / panel | --fds-bg / --fds-surface / --fds-panel | | radius / gap | --fds-radius / --fds-gap | | fontFamily | --fds-font-family | | textXs / textSm / textMd / textBase | Type scale | | controlHeight | --fds-control-h | | raw "--fds-…" | passed through |

Or use the helper:

import { themeToCssVars } from "@designdaddy/form";

const style = themeToCssVars({ primary: "#0f766e", radius: "10px" });

Dark theme

When the host sets data-theme="dark" on a parent (e.g. docs), .fds-root switches to dark tokens automatically. Your theme prop still overrides those variables.

Limits

  • Prefer theme and CSS variables for colors, radius, and type.
  • Scope class overrides under your className (e.g. .my-form .fds-control).
  • Do not remove .fds-root, .fds-shell, or .fds-field from the tree.
  • Import app CSS after @designdaddy/form so overrides win.

Built-in classes

| Class | What it styles | |-------|----------------| | .fds-root | Root + tokens (receives theme / style) | | .fds-shell / __progress / __body / __actions | Layout slots | | .fds-section / __fields | Sections | | .fds-field / __label / __control / __help / __error | Field chrome | | .fds-control | Inputs / textareas | | .fds-select / __trigger | Custom select | | .fds-file-upload | File / media dropzone | | .fds-picker / .fds-cal | Date / time pickers | | .fds-btn / --primary / --ghost | Actions | | .fds-steps | Step indicator |


Exports

import {
  Form,
  FormField,
  FormSection,
  FormShell,
  FormActions,
  FormSteps,
  FieldRenderer,
  FIELD_REGISTRY,
  FIELD_TYPES,
  normalizeType,
  validateFields,
  buildInitialValues,
  flattenFields,
  themeToCssVars,
} from "@designdaddy/form";

Optional CSS path (usually unnecessary):

import "@designdaddy/form/styles.css";

Local pack / publish

cd packages/form
npm run build
npm pack
# then in a host app: npm install ../path/to/designdaddy-form-0.1.0.tgz

Run the docs UI

From the monorepo root:

npm run dev:docs

Open Form in the sidebar. Every page includes Props and Styling sections.

| Path | Content | |------|---------| | /docs/form/overview | Overview, quick start, props summary, styling | | /docs/form/props | Form props by feature | | /docs/form/styling | Live theme={{…}} demo + token table | | /docs/form/attributes | Field attributes | | /docs/form/native-01 … | Native types (5 per page) | | /docs/form/selection-01 … | Selection types | | /docs/form/media-01 … | Media types | | /docs/form/values-01 … | Values & design | | /docs/form/location-01 | Location | | /docs/form/payments-01 … | Payments | | /docs/form/security-01 … | Security / bio | | /docs/form/structure-01 | Structure | | /docs/form/scheduling-01 | Scheduling | | /docs/form/editors-01 … | Editors & AI | | /docs/form/consent-01 | Consent | | /docs/form/layout-01 | section layout |

Hover a sidebar page link to see the types on that page (tooltip).

Folder layout:

packages/form/src/
  Form/           # façade (theme / className / style)
  FormField/
  FormSection/
  FormShell/
  FormActions/
  FormSteps/
  fields/         # FieldRenderer + type implementations
  utils/          # FIELD_TYPES, validateFields, themeToCssVars, …
  styles/form.css