Installation
import { BindableField } from "@octopusdeploy/design-system-octopus-components"
BindableField lets a user either pick a value from a Select / MultiSelect or a TextField where you can bind the field to an Octopus variable by typing, or inserting a variable (e.g. #{Octopus.Environment.Name}) via the InsertVariableActions dropdown. A single toggle switches between the two mode. The toggle is generated automatically and always sits last in the action row.
|
Mode |
Editor rendered |
Toggle shown |
Purpose |
|---|---|---|---|
|
Unbound (default) |
Select (default) or |
Bind to variable (link icon) |
Pick a value from a list |
|
Bound |
TextField |
Unbind (broken-link icon) |
Type/insert a #{Variable} expression |
The two modes hold independent values the selection and the variable expression are separate state the consumer owns. Toggling will not move data between them.
Actions
Actions are declarative shapes that BindableField resolves and wires up for you, or a custom icon-only Button that you can customise yourself.
How they work
We allow two action slots per form field the toggle for Bind/Unbind claims one.
- Toggle Action: BindableField appends the bind/unbind toggle itself so each editor shows an action followed by the toggle (two buttons total).
- Second Action: InsertVariableAction is only valid as a boundAction. Whereas addEntity and custom buttons work in either mode.
- In bound mode the field also shows a clear (✕) control that resets the field value - this is separate from your action.
- The refresh button is not counted as one of the actions and is handled separately with its own dedicated slot. The long term plan is to move it into the Select/Multiselect.
Action shapes
|
Shape |
Ownership |
Available in |
Behaviour |
|---|---|---|---|
|
insertVariable |
Prebuilt |
Bound only (boundAction) |
Opens a dropdown of variables and inserts the chosen one as #{value} at the caret. |
|
addEntity |
Mixed |
Both |
A generic "+" button; the consumer owns whatever it opens. |
|
Raw Button |
Consumer |
Both |
A bespoke icon-only action you manage yourself. |
|
refresh |
Prebuilt |
Select mode only (via AsyncList.refresh) |
Auto-rendered when the items AsyncList defines refresh. Reloads the list. Not configured through the action props. |
Insert Variable Action
An icon-only action button that opens a dropdown of Octopus variables and inserts the selected one (#{VariableName}) into a text field's value.
Refresh (automatic, select mode)
The refresh button is not configured through selectAction / boundAction. It is provided by the data source: when items is an AsyncList whose refresh function is defined, the unbound Select / MultiSelect automatically renders a refresh button.
- Select mode only: It appears alongside the select input.
- Driven by data, not props: Pass an AsyncList with a refresh method to get it; omit refresh and no button renders.
- It's additional to your one custom action: Refresh doesn't count as a selectAction slot, so an async list can show refresh and your addEntity action and the bind toggle at the same time.
- Async feedback: If refresh returns a promise, the arrow spins until it settles and the outcome is announced to screen readers.
Disabled/ReadOnly States
BindableField treats every action button it renders as an edit affordance. Inserting a variable mutates the value, adding an entity feeds the selection, and the bind/unbind toggle switches editors. Setting either disabled or readOnly therefore disables all of the actions, not just the input.
What each state does
|
|
disabled |
readOnly |
|---|---|---|
|
Select / MultiSelect Field (unbound mode) |
Dropdown won't open |
Dropdown won't open |
|
TextField (bound mode) |
Not editable |
Focusable but not editable |
|
Bind / unbind toggle |
Disabled |
Disabled |
|
InsertVariableAction |
Disabled |
Disabled |
|
addEntity Action |
Disabled |
Disabled |
|
Refresh button (async lists) |
Disabled |
Disabled |
Declarative actions vs custom elements
Declarative action shapes e.g. addEntity and InsertVariable are automatically disabled for you this will override A per-any field state.
If you pass a raw icon-only Button element as selectAction or boundAction, it will be rendered exactly as supplied disabling it in the disabled/readonly states is your responsibility which you can set on the button itself.