openpencil/packages/docs/programmable/sdk/api/components/bindable-value.md
Danila Poyarkov 1b7934b98e feat(vue): add property panel primitives
- Add headless PropertySection and accessible SegmentedControl anatomy

- Make PropertyList controlled and exactly typed with an undo-aware editor adapter

- Consolidate SDK metadata loaders and link untranslated docs to canonical pages
2026-07-13 12:36:03 +03:00

62 lines
2 KiB
Markdown

---
title: BindableValue
description: Provider-driven value binding primitives for custom editor controls.
---
<script setup lang="ts">
import BindableValueDemo from '#vue/primitives/BindableValue/demo/BindableValueDemo.vue'
import { data } from './bindable-value.data'
</script>
# BindableValue
BindableValue composes variable or token binding with fields without coupling the field to a
specific editor store. Applications supply a `BindingProvider`; NumberField consumes the context
automatically when nested beneath `BindableValueRoot`.
<BindableValueDemo />
## Anatomy
- `BindableValueRoot` — binding state, policy, resolved value, picker state, and actions
- `BindableValueTrigger` — polymorphic bind-picker trigger
- `BindableValuePicker` — renderless Reka Combobox composition
## Policies
- `detach-on-edit` unbinds targets and keeps the complete interaction in one provider undo batch.
- `readonly-when-bound` blocks field editing, scrubbing, and keyboard stepping.
- `edit-variable` sends changes to `provider.setValue()` instead of changing the target value.
Cancellation rolls back an open provider batch. Providers without undo support still receive
binding changes, with binding snapshots restored where possible.
## Provider example
```ts twoslash
import type { BindingProvider, BindingTarget } from '@open-pencil/vue'
const values = new Map<string, number>([['spacing/md', 16]])
const bindings = new Map<string, string>()
const provider: BindingProvider<number> = {
listVariables: () => [],
filterVariables: () => [],
getBound: () => undefined,
getState: () => 'unbound',
resolve: id => values.get(id),
bind: (target: BindingTarget, variableId) => {
bindings.set(`${target.nodeId}:${target.path}`, variableId)
},
unbind: (target: BindingTarget) => {
bindings.delete(`${target.nodeId}:${target.path}`)
}
}
```
## Generated API reference
The following tables are extracted from the Vue source and JSDoc during the documentation build.
<SdkComponentAPI :components="data.components" />