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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions