AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Mobx React Form Bindings

skill-foxhound87-skills-mobx-react-form-bindings · by foxhound87

Field bindings for mobx-react-form — default rewriter/template, custom bindings, $try utility, per-field mapping, and UI framework integration.

No reviews yet
0 installs
17 views
0.0% view→install

Install

$ agentstack add skill-foxhound87-skills-mobx-react-form-bindings

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-foxhound87-skills-mobx-react-form-bindings)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
1mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Mobx React Form Bindings? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Skill: mobx-react-form-bindings

Mission

Guide the user through creating and using field bindings in mobx-react-form — the mechanism that maps field properties to input component props.

Use this skill when the user needs to:

  • Use default bindings with field.bind()
  • Override bindings per-field or per-render
  • Create custom binding rewriters (prop mapping)
  • Create custom binding templates (prop logic)
  • Integrate with UI frameworks (Material UI, Ant Design, React Aria, etc.)

Architecture

field.bind(props)
  → looks up binding by name (default: 'default')
  → if template exists: calls template({ $try, form, field, props, keys })
  → if rewriter exists: maps field props → component props via rewriter keys
  → returns props object to spread onto input

Default Bindings

Default Rewriter

The built-in rewriter maps standard field properties to HTML input attributes:

// Internal default rewriter:
{
  id: 'id',
  name: 'name',
  type: 'type',
  value: 'value',
  checked: 'checked',
  label: 'label',
  placeholder: 'placeholder',
  disabled: 'disabled',
  autoComplete: 'autoComplete',
  onChange: 'onChange',
  onBlur: 'onBlur',
  onFocus: 'onFocus',
  autoFocus: 'autoFocus',
  inputMode: 'inputMode',
  onKeyUp: 'onKeyUp',
  onKeyDown: 'onKeyDown',
}

Default Template

If defined, the template function receives { $try, form, field, props, keys }:

default: ({ $try, form, field, props, keys }) => ({
  [keys.id]: $try(props.id, field.id),
  [keys.name]: $try(props.name, field.name),
  [keys.type]: $try(props.type, field.type),
  [keys.value]: $try(props.value, field.value),
  [keys.label]: $try(props.label, field.label),
  [keys.placeholder]: $try(props.placeholder, field.placeholder),
  [keys.disabled]: $try(props.disabled, field.disabled),
  [keys.onChange]: $try(props.onChange, field.onChange),
  [keys.onBlur]: $try(props.onBlur, field.onBlur),
  [keys.onFocus]: $try(props.onFocus, field.onFocus),
  [keys.autoFocus]: $try(props.autoFocus, field.autoFocus),
})

> $try() returns the first defined argument — props take precedence over field properties.

Using Bindings in Components

Basic usage

const SimpleInput = observer(({ field, ...props }) => (
  
));

// In parent:

Override props at bind-time

Props passed to bind() take precedence over field-defined properties.

Custom Bindings

Creating a Rewriter (prop mapping)

For UI framework components with different prop names:

const bindings = {
  MaterialTextField: {
    id: 'id',
    name: 'name',
    type: 'type',
    value: 'value',
    label: 'floatingLabelText',    // Material-UI prop name
    placeholder: 'hintText',       // Material-UI prop name
    disabled: 'disabled',
    error: 'errorText',            // Material-UI prop name
    onChange: 'onChange',
    onBlur: 'onBlur',
    onFocus: 'onFocus',
    autoFocus: 'autoFocus',
  },
};

new Form({ fields }, { bindings });

Creating a Template (custom logic)

A template is a function that returns the bindings object. It has full control over the output:

const onBlur = field => (e) => {
  e.preventDefault();
  field.onBlur();
  field.validate(); // validate on blur
};

const bindings = {
  MaterialTextField: ({ $try, form, field, props }) => ({
    type: $try(props.type, field.type),
    id: $try(props.id, field.id),
    name: $try(props.name, field.name),
    value: $try(props.value, field.value),
    floatingLabelText: $try(props.label, field.label),
    hintText: $try(props.placeholder, field.placeholder),
    errorText: field.validating
      ? props.validatingText
      : $try(props.error, field.error),
    errorStyle: field.validating
      ? { background: 'yellow', color: 'black' }
      : {},
    disabled: props.disabled || field.disabled || form.disabled || form.submitting,
    onChange: $try(props.onChange, field.onChange),
    onBlur: $try(props.onBlur, onBlur(field)),
    onFocus: $try(props.onFocus, field.onFocus),
    autoFocus: $try(props.autoFocus, field.autoFocus),
  }),
};

Assigning Bindings to Fields

Via field definition

const fields = {
  username: {
    bindings: 'UppercaseInput', // use custom binding
  },
  price: {
    bindings: 'CurrencyInput',
  },
};

Via separated mode

const bindings = {
  username: 'UppercaseInput',
  price: 'CurrencyInput',
};

new Form({ fields: ['username', 'price'], bindings }, { bindings: customBindings });

Via form constructor

new Form(
  { fields, ... },
  {
    bindings: {
      UppercaseInput: ({ $try, field, props }) => ({ /* ... */ }),
      CurrencyInput: ({ $try, field, props }) => ({ /* ... */ }),
    },
  }
);

Via extended class

class MyForm extends Form {
  bindings() {
    return {
      UppercaseInput: ({ $try, field, props }) => ({ /* ... */ }),
    };
  }
}

Real-World Binding Examples

UppercaseInput

Transforms input to uppercase on every keystroke:

UppercaseInput: ({ $try, field, props }) => ({
  type: 'text',
  name: field.name,
  value: field.value,
  placeholder: field.placeholder,
  onChange: (e) => {
    e.target.value = e.target.value.toUpperCase();
    field.onChange(e);
  },
  /* onBlur, onFocus, disabled... */
}),

CurrencyInput

Strips non-numeric characters, preserves cursor position:

CurrencyInput: ({ $try, field, props }) => ({
  type: 'text',
  value: String(field.value),
  onChange: (e) => {
    const el = e.target;
    const cursor = el.selectionStart;
    const cleaned = el.value.replace(/[^0-9.,]/g, '');
    el.value = cleaned;
    field.onChange(e);
    requestAnimationFrame(() => {
      el.setSelectionRange(Math.min(cursor, cleaned.length), Math.min(cursor, cleaned.length));
    });
  },
}),

DebugInput

Logs every event to console:

DebugInput: ({ $try, field, props }) => ({
  onChange: (e) => {
    console.log(`[Debug] onChange — ${field.path}:`, e.target.value);
    field.onChange(e);
  },
  onBlur: (e) => {
    console.log(`[Debug] onBlur — ${field.path}:`, e.target.value);
    field.onBlur?.(e);
  },
  onFocus: (e) => {
    console.log(`[Debug] onFocus — ${field.path}:`, e.target.value);
    field.onFocus?.(e);
  },
}),

Ant Design Input

AntdInput: ({ $try, field, props }) => ({
  id: field.id,
  name: field.name,
  value: field.value,
  placeholder: field.placeholder,
  status: field.error ? 'error' : undefined,
  onChange: (e) => field.onChange(e),
  onBlur: () => field.onBlur(),
  onFocus: () => field.onFocus(),
  disabled: field.disabled,
}),

React Select

ReactSelect: ({ $try, field, props }) => ({
  name: field.name,
  value: field.extra?.options?.find(o => o.value === field.value),
  options: field.extra?.options || [],
  onChange: (selected) => field.onChange(selected?.value || ''),
  onBlur: field.onBlur,
  onFocus: field.onFocus,
  isDisabled: field.disabled,
}),

The $try Utility

$try() takes unlimited arguments and returns the first defined (non-undefined) value:

$try(props.value, field.value, 'fallback')

Priority: props.valuefield.value'fallback'

This allows component-level overrides while keeping sensible defaults.

Override Default Binding Template Globally

const bindings = {
  default: ({ $try, form, field, props, keys }) => ({
    // your custom default for ALL fields
    ...defaultBindings,
    disabled: props.disabled || field.disabled || form.disabled || form.submitting,
  }),
};

No need to update field bindings props since they already default to 'default'.

Key Takeaways

  1. Rewriters: Simple key mapping — field prop name → component prop name.
  2. Templates: Full control — functions that return the props object.
  3. $try priority: bind(props) args → field properties → fallback.
  4. Per-field assignment: Via bindings field prop or separated bindings object.
  5. Event customization: Override onChange, onBlur, onFocus in templates to transform values.
  6. Framework integration: Create one binding per UI framework component type.

Related Skills

  • [mobx-react-form-api](../mobx-react-form-api/SKILL.md) — Core API prerequisite
  • [mobx-react-form-flat](../mobx-react-form-flat/SKILL.md) — Field definitions with bindings

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.