Relaycode

Vector Input

Dynamic-length list input for Substrate Vec<T> and BTreeSet<T> types with bulk entry support

import { Vector } from "@/components/params/inputs/vector";

<Vector
  name="signatories"
  label="Signatories"
  description="List of signatory accounts"
  client={client}
  typeId={12}
  minItems={2}
  onChange={(val) => console.log("Items:", val)}
/>

Vector Input

The Vector input handles Substrate Vec<T>, BoundedVec<T>, and BTreeSet<T> types by rendering a dynamic list of sub-inputs. It supports both a form mode with individual item inputs and a bulk mode for pasting JSON arrays or line-separated values. The unique prop enables set semantics with strict duplicate detection.

Supported Type Names

The Vector component matches the following type name patterns at priority 40:

  • Any type name matching /^Vec</ (e.g. Vec<AccountId32>, Vec<u8>)
  • Any type name matching /^BoundedVec</ (e.g. BoundedVec<u8, MaxLen>)

The BTreeSet wrapper matches at priority 41:

  • Any type name matching /^BTreeSet</ (e.g. BTreeSet<AccountId32>, BTreeSet<u32>)

Note: Vec<u8> is handled by the higher-priority Bytes component (priority 75) before reaching Vector.

Props

The component extends ParamInputProps with additional collection props:

PropTypeRequiredDescription
namestringYesField identifier used as a prefix for item IDs
labelstringNoDisplay label shown above the list
descriptionstringNoHelp text shown below the list
typeNamestringNoThe SCALE type name (e.g. "Vec<AccountId32>")
isDisabledbooleanNoDisables all controls and item inputs
isRequiredbooleanNoShows a red asterisk next to the label
errorstringNoValidation error message to display
clientDedotClient<PolkadotApi>YesConnected Dedot client for resolving the element type
typeIdnumberNoMetadata type ID for the vector type
valueanyNoExternally controlled value (e.g. from hex decode)
onChange(value: unknown) => voidNoCallback fired with the array of defined values
childrenReact.ReactNodeNoLegacy: explicit child component to clone per item
minItemsnumberNoMinimum number of items (default: 0)
maxItemsnumberNoMaximum number of items (no limit by default)
uniquebooleanNoEnables set semantics: hard duplicate errors, no reorder controls, JSON-only bulk (default: false)

Features

  • Auto-resolves element type: Reads the vector's Sequence typeDef from metadata to find the element type, then uses findComponent to render the correct input for each item.
  • Add/Remove items: An "Add" button appends new items; each item has a remove button (respecting minItems).
  • Reorder items: Up/down chevron buttons let users reorder items within the list (disabled in unique mode since sets are unordered).
  • Bulk entry mode: A toggle switches between form mode (individual inputs) and bulk mode (a textarea accepting JSON arrays or line-separated values).
  • Duplicate detection: Warns when duplicate values are detected in form mode.
  • Constraint display: Shows min/max item constraints when configured.
  • External value sync: Accepts external arrays (e.g. from hex decoding) and syncs them into the form state.
  • Validation: Uses validateVectorConstraints to check min/max item counts.

Unique Mode (BTreeSet)

When unique is enabled (either directly or via the BTreeSet wrapper):

  • Duplicate values are errors (red), not soft warnings (yellow).
  • No reorder controls since sets are unordered.
  • Bulk mode label shows "JSON" instead of "Bulk".
  • JSON-only parsing in bulk mode (no line-separated fallback).
import { BTreeSet } from "@/components/params/inputs/vector";

<BTreeSet
  name="validators"
  label="Validator Set"
  description="Set of unique validator accounts"
  client={client}
  typeId={22}
  onChange={(val) => console.log("Set:", val)}
/>

// Equivalent to:
<Vector {...props} unique />

Type Resolution

import { findComponent } from "@/lib/input-map";

// Matched by /^Vec</ or /^BoundedVec</ at priority 40
findComponent("Vec<AccountId32>", 12, client);
findComponent("BoundedVec<u8, MaxLen>", 18, client);

// Matched by /^BTreeSet</ at priority 41
findComponent("BTreeSet<AccountId32>", 22, client);

Validation

The component uses a Zod schema that expects an array of any values:

const schema = z.array(z.any());

Additionally, validateVectorConstraints checks that the number of defined items falls within the configured minItems and maxItems bounds. In unique mode, duplicate values are treated as validation errors.

Value Format

The onChange callback receives an array of defined values (items that are undefined are filtered out):

// Vec<AccountId32>
["5GrwvaEF...", "5FHneW46..."]

// Vec<u128>
["1000000000000", "2000000000000"]

// BTreeSet<u32> — same array format, must contain unique values
["1", "2", "3"]

The value shape of each element depends on the resolved inner component's output.