You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* feat(directives): attribute/tag adopt the shared textStyle block (size + color)
The `attribute` and `tag` directives previously supported only a flat
`textSize` field (added in #491). The shared TextStyle abstraction
(src/layout/style/text-style.ts) already documented attribute/tag lines as
a consumer, but they were never wired to it.
Wire them into the shared `textStyle: { size, color }` block — the same
shape edgeStyle/atomStyle use — so each attribute/tag line can set its own
color as well as size. `textSize` moves to `textStyle.size` as a clean
break (no deprecate-and-warn): textSize only shipped in #491, so there is
no back-compat burden.
Changes:
- layoutspec: AttributeDirective/TagDirective carry `textStyle?: TextStyle`,
parsed via the shared parseTextStyle; drop normalizeAttrTextSize.
- layoutinstance: the per-attribute channel carries the whole TextStyle;
getAttributeTextSize -> getAttributeTextStyle; box sizer reads .size.
- interfaces/webcolatranslator: attributeSizes -> attributeTextStyles.
- webcola-cnd-graph: attribute/tag tspans get font-size from .size and
fill from .color (null = inherit the themed label, so dark mode adapts).
- spec-editor registry: attribute/tag expose the shared textStyle group.
- docs: YAML_SPECIFICATION.md, site/directives.md, site/yaml-reference.md,
and the agent-manifest (1.8.0 -> 1.9.0) document size + color.
- tests: new attribute-tag-textstyle suite (parse + end-to-end for both
directives, incl. sparse color-only and absent cases) — #491 had none.
- bump 3.0.1 -> 3.1.0 (minor: additive optional fields).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* test(spec-editor): cover attribute/tag textStyle in the no-code builder
The no-code editor (SpecEditor/BuilderView) is driven by the registry, so
the prior commit's registry change already wires attribute/tag to the
shared textStyle group — FieldRenderer renders `kind: 'group'` generically
(same path edgeStyle/atomStyle use) and the legacy NoCodeView shim passes
params through untouched. Add explicit coverage + fix stale docs:
- Assert attribute/tag expose a `textStyle` group field with children
[size, color] in the directive registry.
- Ingest + round-trip an attribute textStyle block and a tag textStyle
block through the codec (parseYamlToState → serializeStateToYaml).
- Fix the registry header shape-manifest comment: attribute/tag now show
`textStyle?:{size,color}` (they never listed the field).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/YAML_SPECIFICATION.md
+16-10Lines changed: 16 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -693,7 +693,9 @@ Converts edge relationships into node attributes (displayed as key-value pairs o
693
693
field: <field-name> # Required: Relation to convert to attribute
694
694
selector: <unary-selector> # Optional: Filter which source atoms apply
695
695
filter: <n-ary-selector> # Optional: Filter which tuples to include
696
-
textSize: <size> # Optional: small | normal | large (default: normal)
696
+
textStyle: # Optional: style the attribute line (shared block)
697
+
size: <small|normal|large> # font size relative to the node label (default: normal)
698
+
color: <color> # text color (any CSS color)
697
699
```
698
700
699
701
**Fields:**
@@ -703,13 +705,14 @@ Converts edge relationships into node attributes (displayed as key-value pairs o
703
705
| `field` | ✅ Yes | string | Name of the relation to display as attribute |
704
706
| `selector` | ❌ No | string | Unary selector to filter source atoms |
705
707
| `filter` | ❌ No | string | N-ary selector to filter specific tuples |
706
-
| `textSize` | ❌ No | `small` \| `normal` \| `large` | Size of this attribute's text, relative to the node label. Default `normal`. |
708
+
| `textStyle.size` | ❌ No | `small` \| `normal` \| `large` | Size of this attribute's text, relative to the node label. Default `normal`. |
709
+
| `textStyle.color` | ❌ No | string | Text color of this attribute's line (any CSS color). Default inherits the node label color. |
707
710
708
711
**Behavior:**
709
712
- Removes the edge from the graph
710
713
- Displays the target value as an attribute on the source node
711
714
- Multiple targets become a list
712
-
- `textSize` controls the line's font size: `large`renders **bigger** than the node's label, `normal` is the default (smaller than the label), and `small` is smaller still. The node box grows/shrinks to fit.
715
+
- `textStyle` is the same shared block edges and atoms use. `size` controls the line's font size: `large`renders **bigger** than the node's label, `normal` is the default (smaller than the label), and `small` is smaller still — the node box grows/shrinks to fit. `color` sets the line's text color (unset = inherit the node's label color, so dark mode still adapts).
713
716
714
717
**Examples:**
715
718
@@ -728,10 +731,10 @@ Converts edge relationships into node attributes (displayed as key-value pairs o
728
731
field: status
729
732
filter: 'status & (univ -> Active)'
730
733
731
-
# Emphasize a key attribute — rendered larger than the node label
734
+
# Emphasize a key attribute — larger than the node label, in red
732
735
- attribute:
733
736
field: balance
734
-
textSize: large
737
+
textStyle: { size: large, color: "#c0392b" }
735
738
```
736
739
737
740
---
@@ -745,7 +748,9 @@ Adds computed attributes to nodes based on selector evaluation. Unlike `attribut
745
748
toTag: <unary-selector> # Required: Selector for atoms to receive the tag
746
749
name: <attribute-name> # Required: Name of the attribute to display
747
750
value: <n-ary-selector> # Required: Selector whose result becomes the value
748
-
textSize: <size> # Optional: small | normal | large (default: normal)
751
+
textStyle: # Optional: style the tag line (shared block)
752
+
size: <small|normal|large> # font size relative to the node label (default: normal)
753
+
color: <color> # text color (any CSS color)
749
754
```
750
755
751
756
**Fields:**
@@ -755,13 +760,14 @@ Adds computed attributes to nodes based on selector evaluation. Unlike `attribut
755
760
| `toTag` | ✅ Yes | string | Unary selector for atoms that receive this tag |
756
761
| `name` | ✅ Yes | string | Attribute name to display |
| `textSize` | ❌ No | `small` \| `normal` \| `large` | Size of this tag's text, relative to the node label. Default `normal`. |
763
+
| `textStyle.size` | ❌ No | `small` \| `normal` \| `large` | Size of this tag's text, relative to the node label. Default `normal`. |
764
+
| `textStyle.color` | ❌ No | string | Text color of this tag's line (any CSS color). Default inherits the node label color. |
759
765
760
766
**Behavior:**
761
767
- Does NOT remove edges (unlike `attribute`)
762
768
- For binary results: displays as `name: value`
763
769
- For n-ary results: displays as `name[key1][key2]: value`
764
-
- `textSize` controls the line's font size: `large`renders **bigger** than the node's label, `normal` is the default (smaller than the label), and `small` is smaller still.
770
+
- `textStyle` is the same shared block edges and atoms use. `size` controls the line's font size: `large`renders **bigger** than the node's label, `normal` is the default (smaller than the label), and `small` is smaller still. `color` sets the line's text color (unset = inherit the node's label color).
765
771
766
772
**Examples:**
767
773
@@ -778,12 +784,12 @@ Adds computed attributes to nodes based on selector evaluation. Unlike `attribut
778
784
name: score
779
785
value: grades
780
786
781
-
# De-emphasize a secondary tag — rendered smaller than the default
787
+
# De-emphasize a secondary tag — smaller than the default, muted gray
Copy file name to clipboardExpand all lines: site/directives.md
+12-6Lines changed: 12 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -453,22 +453,25 @@ Converts an edge relationship into a **label on the source node**. The edge is r
453
453
field: <field-name> # Required
454
454
selector: <unary-selector> # Optional
455
455
filter: <n-ary-selector> # Optional
456
-
textSize: <size> # Optional: small | normal | large
456
+
textStyle: # Optional: shared text-style block
457
+
size: <small|normal|large> # font size relative to the node label
458
+
color: <color> # text color (any CSS color)
457
459
```
458
460
459
461
| Field | Required | Type | Description |
460
462
|-------|----------|------|-------------|
461
463
| `field` | Yes | string | Relation to display as an attribute |
462
464
| `selector` | No | string | Filter by source atom type |
463
465
| `filter` | No | string | Filter specific tuples |
464
-
| `textSize` | No | `small` \| `normal` \| `large` | Size of the attribute text relative to the node label (default `normal`) |
466
+
| `textStyle.size` | No | `small` \| `normal` \| `large` | Size of the attribute text relative to the node label (default `normal`) |
467
+
| `textStyle.color` | No | string | Text color of the attribute line (default inherits the node label color) |
465
468
466
469
### What Happens
467
470
468
471
- The edge for this field is **removed** from the graph
469
472
- The target value appears as `field: value` on the source node
470
473
- Multiple targets become a comma-separated list
471
-
- `textSize` scales the line's font: `large`is bigger than the node label, `normal` (default) is smaller, `small` smaller still; the node box resizes to fit
474
+
- `textStyle`is the same shared block edges and atoms use. `size` scales the line's font (`large` bigger than the node label, `normal` default, `small` smaller still; the node box resizes to fit); `color` sets its text color (unset = inherit the node label color)
textSize: <size> # Optional: small | normal | large
530
+
textStyle: # Optional: shared text-style block
531
+
size: <small|normal|large> # font size relative to the node label
532
+
color: <color> # text color (any CSS color)
528
533
```
529
534
530
535
| Field | Required | Type | Description |
531
536
|-------|----------|------|-------------|
532
537
| `toTag` | Yes | string | Selector for atoms that receive the tag |
533
538
| `name` | Yes | string | Label name to display |
534
539
| `value` | Yes | string | Selector whose result becomes the value |
535
-
| `textSize` | No | `small` \| `normal` \| `large` | Size of the tag text relative to the node label (default `normal`) |
540
+
| `textStyle.size` | No | `small` \| `normal` \| `large` | Size of the tag text relative to the node label (default `normal`) |
541
+
| `textStyle.color` | No | string | Text color of the tag line (default inherits the node label color) |
536
542
537
543
### Behavior
538
544
539
545
- Does **NOT** remove edges (unlike `attribute`)
540
546
- For binary results: displays as `name: value`
541
547
- For higher-arity results: displays as `name[key1][key2]: value`
542
-
- `textSize` scales the line's font: `large`is bigger than the node label, `normal` (default) is smaller, `small` smaller still
548
+
- `textStyle`is the same shared block edges and atoms use. `size` scales the line's font (`large` bigger than the node label, `normal` default, `small` smaller still); `color` sets its text color (unset = inherit the node label color)
0 commit comments