Desde

Editor guide

Select and inspect

Pick the Select tool, click an element, and read what Editor knows about it. Its component, its props, where its styles come from, and its place in your source.

Selecting is how you tell Editor what you want to work on. A selection is not just a highlighted box: it carries the component identity, the live prop values, the style provenance, and the exact file, line and column the element was written at. Everything on the Editing page starts here.

Pick the Select tool#

Pick Select from the tool picker in the floating toolbar under the header. Until you do, clicks go to your prototype and nothing selects. See The workspace for why Navigate is the default.

With Select active:

  • Hovering outlines the element under the cursor.
  • Clicking selects it. The Inspector appears in the Edit tab of the right rail.
  • Right-clicking opens a per-element menu.
  • Pressing Escape clears the selection completely.

Escape is ignored while you are typing in a field or while a dialog or menu is open, so it will not throw away work mid-edit.

What actually gets selected#

A click resolves to one of two things, and the Inspector header tells you which:

  • A component: the heading is the component's name (KButton, ProtoCatalogCard) and the line under it is the source file it is defined in.
  • A plain element: the heading is the tag name (div, span). No component file, because there is no component to point at.

The difference matters. Component props are only offered for a component selection; a raw div inside a component gets styles, classes and text only. Swap and Detach need a component selection too, but they are dormant: absent unless you set lanes.swap and lanes.detach, described below.

If you clicked something inside a design-system component (an SVG path inside an icon, for instance), Editor walks up to the enclosing component where it can, so the actions you get belong to the component rather than to a bare <path>. The icon picker is one of those actions, and it rides lanes.swap with the rest of the swap lane.

Swap, Detach and the icon picker are off by default#

Three controls are dormant, and by default you will not see them at all: Swap component, Detach component, and the icon picker. Turn them back on per lane, in desde.config.json at your prototype's root:

{
  "lanes": {
    "detach": true,
    "swap": true
  }
}

See editor configuration for where that file lives and how a badly shaped block behaves.

The reason is worth stating plainly, because it is not a bug and not a work in progress. Both applicators rewrite Vue single-file-component syntax and neither has a React equivalent, so on a React project these two controls were offered for an edit that could never land. On Vue, where they do work, nobody had used them. Removing the offering was cheaper than writing and maintaining two React applicators for a capability with no users. Nothing was deleted: the applicators and their tests are intact, and opting in restores all three controls exactly as they were.

The icon picker rides lanes.swap rather than a switch of its own because it is a swap: it replaces one icon component with another through the same applicator, so it carries the same Vue-only limit. { "lanes": { "swap": true } } brings back the picker and Swap component together; there is no way to have one without the other.

The gate is not cosmetic. With a lane dormant the edit API refuses that kind outright, with a message naming the config key, so a stale browser tab cannot reach it either.

The Inspector#

The Inspector renders only the sections that apply to the current selection, top to bottom.

Identity#

The component or tag name, and the file it comes from (shortened, with the full path on hover). A ⋮ menu next to it offers, where applicable:

  • Edit component: opens the component on its own in the preview, rendered once per variant so you see a grid instead of a single instance in page context.
  • Swap component: replace this usage with a different component. Dormant: needs lanes.swap.
  • Detach component: inline the component's markup at this call site. Dormant: needs lanes.detach.

When Detach is enabled it is still offered only for components authored in your own repo. Editor never rewrites files under node_modules.

Variants and props#

One row per prop the component's manifest declares, with a control chosen by the prop's type: a switch for booleans, a dropdown for finite choices (the variant enums: appearance, size, and the like), a text field, or a number field. Object, array, event, function, slot and token props render read-only; there is no editor for them yet.

Each control shows the value on this instance when there is one, falling back to the manifest's default. Selecting a second button of the same type shows that button's own values, not the first one's.

When no manifest exists for the component, this section is replaced by a plainer Props section listing the values that are currently set, as text fields. It is graceful degradation, not a substitute: without a manifest, Editor cannot know about props you have not set, or their types. See design-system grounding for where manifests come from.

Attributes#

Fallthrough attributes the parent passed to this instance that the component does not formally declare: placeholder, data-testid, required. Editable as text.

Style#

A State bar first: default, plus hover / focus / dark. Picking one points every control below it at that state's classes; a dot marks states this element already has overrides for. If a breakpoint is active in the toolbar, a chip shows which one you are editing.

Then the sections, each a set of controls rather than a raw style dump:

Section Covers
Spacing Padding and margin, all sides or per side
Align & size Flex/grid alignment grid, text alignment, width
Color Background, text and border colours, with your design tokens as swatches
Border Width, style, radius, colour (per side and per corner)
Typography Size, weight, family, leading, tracking, colour, alignment
Shadow The shadow scale

Under a value you may see a From: line. That is the provenance of the rendered value: the CSS rule that actually won the cascade, any var(--token) hops, and the stylesheet that defines it. Click it for the full chain. It exists because guessing backwards from a computed colour to "which Tailwind shade is this" produces confident wrong answers; the From line reports where the value genuinely comes from instead.

Provenance is also what decides whether editing a style asks you a question first. See Editing.

DOM#

The editable text on this element, one field per piece, plus a Classes field holding the element's space-separated class list. Some text renders read-only with a reason: that is Editor telling you it can see the text but cannot safely trace it back to a single place in source.

Conditional text#

Appears only when the element's content is a ternary: {{ isNew ? 'New' : 'Existing' }}. You get one field per branch, labelled with the condition that produces it, so you can edit the "true" and "false" copy separately without touching the condition.

The Structure tree#

Above the Inspector, the Structure panel mirrors your prototype's tree the way a Layers panel mirrors a frame. Components are shown in the accent colour, plain elements in grey, text in lighter italic grey; a component's package name appears on the right when it comes from a library.

Selection is two-way: clicking a row selects that element in the prototype, and selecting in the prototype expands and highlights the matching row. Hovering a row outlines the element in the preview without committing to it. The refresh button re-reads the tree if the page has changed underneath you.

Right-clicking a row is the entry point for structural edits: insert, unwrap, flatten a conditional, delete, and, with lanes.detach enabled, detach. Dragging a row reorders it. Both are covered in Editing.

Right-clicking inside the prototype#

With Select active, right-clicking an element in the preview opens a menu with:

  • Open in editor: opens the file the element was authored in, in Editor's own code view, at the right line. Dormant by default (EDITOR_CODE_VIEW, product decision 2026-08-14: "it needs some visual work and I don't want to ship it half finished"): unless you turn it on, the item does not render at all.
  • Open in VS Code: the same file and line, via a vscode:// link. Dormant by default (EDITOR_VSCODE_LINK, product decision 2026-08-18) for a different reason: it assumes an editor choice the product otherwise never makes for you.
  • A text field that starts a new chat about this element. The element is already the selection, so the agent gets it as context automatically.

Turn either back on in .desde/config.json at your prototype's root:

{
  "editor": {
    "codeView": true,
    "vscodeLink": true
  }
}

or with the EDITOR_CODE_VIEW=1 / EDITOR_VSCODE_LINK=1 environment variables. Nothing was deleted for either: the file-editor pane, its read route, the vscode:// handler and their tests all stay intact, and opting in restores the item exactly as it was. The code view is also gated server-side, on the same config, so a stale browser tab cannot reach its read route while it is off; "Open in VS Code" assigns a URL and calls no API, so its one client-side gate is the whole feature.

When either is on, both "Open in…" items are disabled when Editor could not attribute the click to a source location, which is itself useful information.

How a selection maps to source#

When Editor supervises your Vite dev server, it stamps a data-desde-src="file:line:column" attribute onto the elements your templates produce. The stamping happens in memory as files are served: nothing is written into your repo, and the attribute is gone the moment you stop Editor.

That attribute is the whole link between a click in the browser and a position in your source. It is why the Inspector can name the file, why edits land on the exact tag you selected rather than on a string match somewhere in the file, and why there is no "find and replace" step that could hit the wrong occurrence.

Two consequences follow directly:

  • An element with no source mapping cannot be edited structurally. Markup rendered from inside a library's own compiled code has no tag of yours to rewrite. Editor greys out the actions instead of guessing.
  • An element inside a reused component is authored once. The tree shows N copies on screen; source has one. That gap is what the scope dialogs exist to resolve. See Editing.

Selection-driven edits land in .vue, .tsx and .jsx files. Two lanes reach further: the AI-repair lane also accepts .ts, and a "change the token" style edit writes the .css file the token is defined in. Everything else is refused at the boundary.

Next#

  • Editing: change what you have selected
  • Limits: what refuses, and why