Blank edge style colors are not dropped at the read boundary
- Dominant language
- TypeScript
- Stars
- 481
- Forks
- 108
- Avg merge
- 6d 8h
- Merged PRs (30d)
- 5
Description
An edge style stored with an empty color renders as no color at all. The equivalent defect for vertex styles was fixed in #2102; edges were left because they need a transform that does not exist yet.
## Why it happens
`stylingParser.ts` validates every color as a bare optional string, so a styling file carrying `"lineColor": ""` is stored verbatim. `resolveEdgeStyle` (`core/StateProvider/graphStyles.ts`) then plain-spreads the user entry over the defaults:
```ts
return { type, ...appDefaultEdgeStyle, ...user } as const;
```
A spread only skips *absent* keys, so `""` overrides the default. Consumers read the value directly — `useGraphStyles` passes `lineColor` to cytoscape `line-color` and `labelColor` to `text-background-color` — and an empty string is not a color, so the edge or its label badge renders without one.
Three fields are exposed, all from `EdgeVisualStyle` / `LabelVisualStyle`:
- `lineColor` (default `#b3b3b3`)
- `labelColor` (default `#17457b`)
- `labelBorderColor` (default `#17457b`)
## Fix
Mirror what #2102 did for vertices. That fix lives in `transformVertexStyles`, a read-time transform wired onto `user-vertex-styles` — the home the `read-time-transform-for-persisted-values` ADR assigns to intra-key value normalization, and the point where persisted storage and file import converge.
`user-edge-styles` has **no** transform today, so this needs:
1. A new `core/StateProvider/edgeStylesTransform.ts` exporting `transformEdgeStyles`, dropping the three color fields when blank (use `.trim()` so whitespace-only counts).
2. Wiring in `storageAtoms.ts`, alongside the existing `reconcile` for that key.
3. Tests in the `describe("backward compatibility: ...")` form the vertex transform test uses.
Drop the field rather than substituting a default, so "no user value" stays the representation and the style keeps following the app default if it ever changes. Follow the vertex version, which names the color fields explicitly rather than cleaning all strings — for edges there is no `iconUrl` equivalent, but being explicit keeps the two transforms symmetrical.
## Notes
Pre-existing; not introduced by #2102. Reachable through a hand-edited or third-party styling file, or storage written by an older build — the color picker in the UI cannot produce an empty value.
---
> [!IMPORTANT]
> Internal only — this issue is maintained by the core team and is not accepting external contributions.
Contributor guide
Research direction
Start with transformVertexStyles and its backward-compatibility tests, then inspect core/StateProvider/storageAtoms.ts and the user-edge-styles atom. Run the related StateProvider tests and verify that blank or whitespace-only lineColor, labelColor, and labelBorderColor are omitted while existing nonblank values remain unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend, testing
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 25/100