Skip to content

Consider a moveField() / reorder helper on DataField containers #7

Description

@sambhav-aggarwal

Motivation

DataField->items is a public array, so consumers can reorder children directly — but it's clunky:

```php
// Move 'phone' to the front
$items = array_filter($df->items, fn ($i) => $i->key !== 'phone');
$df->items = [$df->phone, ...array_values($items)];
```

A helper would read much better. Tracking as an issue rather than implementing now because the right shape depends on real-world usage.

Design options

Numeric position only

```php
$df->moveField('phone', 0); // to index 0
$df->moveField('phone', -1); // to end (Python-style)
```

Simple. Doesn't cover the common "after another sibling" intent without an extra indexOf() lookup.

Sibling-relative

```php
$df->moveField('phone', before: 'email');
$df->moveField('phone', after: 'address');
```

Reads well at the call site. Both keyword args (before / after) are mutually exclusive — needs validation. Doesn't cover "move to absolute position".

Hybrid

```php
$df->moveField('phone', 0); // by index
$df->moveField('phone', before: 'email'); // by sibling
$df->moveField('phone', after: 'address'); // by sibling
```

Most flexible. Slight API surface bloat.

Error semantics

  • Missing target key (moveField('phone', before: 'no_such_key')): throw InvalidArgumentException.
  • Missing moved key (moveField('no_such_key', 0)): throw InvalidArgumentException.
  • Container vs leaf: throw LogicException on leaves (consistent with addField / removeField).
  • Container in cast mode only — row mode reorders via the sort_order column.

Open questions

  • Should this only operate on direct children, or also accept dotted paths (moveField('appearance.dark_mode', 0))?
  • Worth a fluent return ($df->moveField(...)->moveField(...)) — probably yes, matches addField / removeField.

When to do it

Defer until at least one consumer hits the friction so we know what shape they actually need. Until then, direct \$df->items manipulation works.

Related

Surfaced during 0.4.0 review as a nice-to-have. Not blocking.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions