# DataProxy

```ts
import { DataProxy } from 'cx/ui';
```



DataProxy creates aliases for store bindings with optional custom getter/setter logic. The simplest use case is creating a two-way alias for a binding.

## Example

```tsx
import { createModel } from "cx/data";
import { DataProxy, LabelsTopLayout } from "cx/ui";
import { Slider } from "cx/widgets";

interface PageModel {
  level: number;
}

const m = createModel<PageModel>();

interface ProxyModel {
  $level: number;
}

const mProxy = createModel<ProxyModel>();

export default (
  <div>
    <div class="text-sm font-medium leading-none mb-2">Original</div>
    <Slider value={m.level} />

    <DataProxy value={m.level} alias={mProxy.$level}>
      <div class="text-sm font-medium leading-none mt-4 mb-2">Alias</div>
      <Slider value={mProxy.$level} />
    </DataProxy>
  </div>
);

```

Moving either slider affects the other since they both point to the same underlying value.

## Custom Transformations

Use the `data` property to define multiple aliases with custom getter and setter logic:

- `expr` - Defines getter logic using a computable or expression
- `set` - Defines setter logic (receives value and instance with store)

Omitting the `set` property makes the alias read-only.

```tsx
import { createModel } from "cx/data";
import { computable, DataProxy, Instance, LabelsTopLayout } from "cx/ui";
import { Slider } from "cx/widgets";

interface PageModel {
  level: number;
}

const m = createModel<PageModel>();

interface ProxyModel {
  $inverted: number;
  $readOnly: number;
}

const mProxy = createModel<ProxyModel>();

export default (
  <div>
    <LabelsTopLayout>
      <Slider value={m.level} label="Original" />
    </LabelsTopLayout>

    <DataProxy
      data={{
        $inverted: {
          expr: computable(m.level, (v) => 100 - v),
          set: (value: number, { store }: Instance) => {
            store.set(m.level, 100 - value);
          },
        },
        $readOnly: {
          expr: computable(m.level, (v) => v),
        },
      }}
    >
      <LabelsTopLayout>
        <Slider value={mProxy.$inverted} label="Inverted" />
        <Slider value={mProxy.$readOnly} label="Read-only" />
      </LabelsTopLayout>
    </DataProxy>
  </div>
);

```

<Note type="warning">
  When using two-way mapping, both getter and setter must be reversible without
  data loss. For any alias value, you should be able to recover all store values
  used to calculate it.
</Note>

<Note type="info">
  Prefix alias names with `$` to avoid name shadowing, which can cause infinite
  get-set loops and stack overflow errors.
</Note>

## Configuration

| Property    | Type      | Description                                                                     |
| ----------- | --------- | ------------------------------------------------------------------------------- |
| `value`     | `Prop`    | Binding, computable, expression, or object with `expr` and/or `set` properties. |
| `alias`     | `string`  | Alias name for the computed value.                                              |
| `data`      | `object`  | Object mapping alias names to `{ expr, set }` configurations.                   |
| `immutable` | `boolean` | Prevent mutations to the parent store.                                          |