Perspective JSON Completions
The LSP provides intelligent completions for Perspective view.json files, including component types, properties, event handlers, and bindings — making it easier to edit Perspective views in raw JSON.
Why Edit Perspective JSON?
While the Designer provides a visual editor, editing raw JSON offers:
- Version control - Better diff and merge support
- Bulk operations - Search/replace across components
- Templating - Copy/paste component structures
- Scripting - Programmatic view generation
- Speed - Faster than clicking through the Designer
How It Works
The LSP detects Perspective view.json files by:
- Filename pattern:
view.json,page.json - Path pattern:
com.inductiveautomation.perspective/views/ - Content detection: JSON with
"type": "View"or"type": "Container"
Once detected, you get completions for:
- Component types
- Component properties
- Event handlers
- Binding types
- Style classes
Component Type Completions
When adding a new component, get completions for all available types:
{
"type": "ia.container.flex",
"children": [
{
"type": "ia. // <- Complete to see all component types
}
]
}
Display Components
ia.display.label- Text labelsia.display.markdown- Markdown rendereria.display.image- Imagesia.display.icon- SVG iconsia.display.video- Video playeria.display.gauge- Circular gaugesia.display.led- LED indicators
Input Components
ia.input.button- Buttonsia.input.textfield- Text inputia.input.textarea- Multi-line textia.input.numeric- Number inputia.input.checkbox- Checkboxesia.input.radio- Radio buttonsia.input.dropdown- Dropdownsia.input.switch- Toggle switchesia.input.slider- Sliders
Container Components
ia.container.flex- Flexbox containersia.container.coord- Coordinate containersia.container.column- Column layoutsia.container.row- Row layoutsia.container.tabcontainer- Tabsia.container.popup- Popup windows
Chart Components
ia.chart.timeseries- Time series chartsia.chart.pie- Pie chartsia.chart.bar- Bar chartsia.chart.scatter- Scatter plotsia.chart.ohlc- OHLC charts
Data Components
ia.display.table- Data tablesia.display.tree- Tree viewsia.display.dropdown- Selection dropdowns
Property Completions
After typing "props":, get completions for properties specific to the component type:
{
"type": "ia.input.button",
"props": {
"text": "Click Me",
" // <- Complete to see: enabled, visible, style, etc.
}
}
Common Properties
Available on all components:
style- Component stylingcustom- Custom propertiesposition- Position metadata
Type-Specific Properties
Each component type has unique properties:
Button:
text- Button labelenabled- Enable/disable stateprimary- Primary button style
Label:
text- Label texttextAlign- Text alignmenticon- Icon configuration
Table:
data- Table datasetcolumns- Column configurationselection- Selection mode
Event Handler Completions
When defining events, get completions for available event types:
{
"type": "ia.input.button",
"events": {
" // <- Complete to see: onClick, onMouseEnter, onMouseLeave, etc.
}
}
Event Types
Mouse Events:
onClick- Mouse clickonMouseEnter- Mouse enteronMouseLeave- Mouse leaveonMouseDown- Mouse button downonMouseUp- Mouse button up
Component Events:
onStartup- Component initializationonShutdown- Component cleanuponChange- Value changeonActionPerformed- Action triggered
Event Script Completions
Within event handlers, get completions for the event payload structure:
{
"events": {
"onClick": {
"0": {
"type": "script",
"script": "// In the decoded Python script:\nself. // <- Complete to see: view, session, etc."
}
}
}
}
Event scripts have access to:
self- Component referenceself.view- Parent viewself.session- Session objectevent- Event payload (for some events)
Binding Type Completions
When adding bindings, get completions for binding types:
{
"props": {
"text": {
"binding": {
"type": " // <- Complete to see: property, tag, query, expression
}
}
}
}
Binding Types
property - Bind to another property:
{
"type": "property",
"config": {
"path": "view.params.title"
}
}
tag - Bind to a tag:
{
"type": "tag",
"config": {
"path": "[default]Path/To/Tag"
}
}
query - Bind to a query:
{
"type": "query",
"config": {
"queryPath": "MyQuery",
"params": {}
}
}
expression - Bind to an expression:
{
"type": "expression",
"config": {
"expression": "{view.params.multiplier} * 2"
}
}
Style Completions
Get completions for CSS-like style properties:
{
"props": {
"style": {
" // <- Complete to see: backgroundColor, color, fontSize, padding, etc.
}
}
}
Style Properties
Layout:
display- Display mode (flex, block, inline)flexDirection- Flex direction (row, column)justifyContent- Main axis alignmentalignItems- Cross axis alignmentpadding- Inner spacingmargin- Outer spacing
Typography:
fontSize- Font sizefontWeight- Font weight (bold, normal)color- Text colortextAlign- Text alignment
Background:
backgroundColor- Background colorbackgroundImage- Background image URLopacity- Transparency (0-1)
Border:
border- Border shorthandborderRadius- Corner radiusborderColor- Border colorborderWidth- Border thickness
Position Completions
For coordinate containers, get completions for position properties:
{
"meta": {
"position": {
" // <- Complete to see: x, y, width, height
}
}
}
Validation
The LSP validates Perspective JSON against the schema:
Component Type Validation
{
"type": "ia.invalid.component" // ❌ Error: Unknown component type
}
Required Property Validation
{
"type": "ia.input.button"
// ❌ Warning: Missing required 'props' property
}
Property Type Validation
{
"props": {
"enabled": "true" // ❌ Error: Expected boolean, got string
}
}
Tips
Use the Component Tree
Press <localleader>it to open an interactive component tree that shows the entire view structure:
View
├── Root (ia.container.flex)
│ ├── Header (ia.display.label)
│ └── Content (ia.container.column)
│ ├── Button1 (ia.input.button)
│ └── Table1 (ia.display.table)
Navigate with <CR>, delete with d, refresh with R.
Format JSON Regularly
Use :IgnitionFormat or <localleader>if to auto-format JSON and ensure consistent indentation (Ignition Designer uses tabs).
Extract Common Styles
Create reusable style objects:
{
"custom": {
"styles": {
"headerStyle": {
"fontSize": "24px",
"fontWeight": "bold",
"color": "#333"
}
}
},
"children": [
{
"props": {
"style": "{view.custom.styles.headerStyle}"
}
}
]
}
Use Bindings for Dynamic Content
Instead of hardcoded values:
{
"props": {
"text": {
"binding": {
"type": "tag",
"config": {"path": "[default]Motor1/Speed"}
}
}
}
}
Troubleshooting
"No completions in view.json"
-
Ensure the file is detected as Perspective:
:set filetype? # Should show 'json.perspective' or 'json' -
Check the file path matches Perspective patterns:
/path/to/com.inductiveautomation.perspective/views/MyView/view.json -
Verify the JSON root has perspective markers:
{
"type": "View", // or "Container"
"rootContainer": { ... }
}
"Completions are incomplete"
The perspective schema is continuously updated. Make sure you have the latest LSP version:
pip install --upgrade ignition-lsp