format.color on a selected chart colours the chart's text

Font Color with a chart selected answered and changed nothing: a chart
has no text runs to colour. It now sets the chart's text colour (title,
axes, legend and data labels), the same thing chart.options {textColor}
sets; a mixed selection still colours the other shapes' runs.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Zach Berry
2026-10-23 19:57:50 -05:00
co-authored by Claude Fable 5.1
parent a48a2d706a
commit 1b03ae95de
2 changed files with 32 additions and 1 deletions
+22 -1
View File
@@ -4,7 +4,7 @@
use deckcraft_model::edit as ed;
use deckcraft_model::resolve;
use deckcraft_model::text::{Align, Anchor, AutoFit, Bullet, Caps, ParaProps, RunProps, Spacing, Strike, TabStop, TextDir};
use deckcraft_model::{ColorRef, ColorTransform, Effects, Fill, Line, SchemeSlot, Shape};
use deckcraft_model::{ColorRef, ColorTransform, Effects, Fill, Line, SchemeSlot, Shape, ShapeKind};
use serde_json::{Value, json};
use super::text::{format_body, format_para, format_run};
@@ -340,6 +340,27 @@ fn shrink(s: &mut Session, _p: &Value) -> Result<Value> {
}
fn color(s: &mut Session, p: &Value) -> Result<Value> {
let c = color_param(p, "color").ok_or_else(|| bad("format.color", "missing or invalid `color`"))?;
// A selected chart has no runs: Font Color colours its text (title, axes, legend, labels),
// which used to answer and change nothing.
let st = s.doc()?;
if st.selection.text.is_none() {
let charts: Vec<ShapeId> =
st.selection.shapes.iter().copied().filter(|id| matches!(st.shape(*id).map(|sh| &sh.kind), Some(ShapeKind::Chart(_)))).collect();
let only_charts = charts.len() == st.selection.shapes.len();
if !charts.is_empty() {
let tc = c.clone();
edit_shapes(s, &json!({"ids": charts}), "format.color", |sh| {
if let ShapeKind::Chart(ch) = &mut sh.kind {
ch.text_color = Some(tc.clone());
ch.raw = None;
}
Ok(())
})?;
if only_charts {
return ok();
}
}
}
format_run(s, &move |r| r.fill = Some(Fill::solid(c.clone())))
}
/// `a:alpha` for `transparency` (0–1) on `c`, replacing any alpha it had; fully opaque drops it.
+10
View File
@@ -4428,3 +4428,13 @@ fn chart_options_text_color_sets_clears_and_refuses() {
s.execute("chart.options", &json!({"id": id, "textColor": null})).unwrap();
assert_eq!(chart_of(&s, id).text_color, None);
}
/// Font Color on a selected chart colours the chart's text (it used to answer and change nothing).
#[test]
fn format_color_on_a_selected_chart_sets_its_text_color() {
let mut s = session();
let id = s.execute("insert.chart", &json!({"type": "column", "title": "Sales"})).unwrap()["id"].as_u64().unwrap();
s.execute("edit.select", &json!({"ids": [id]})).unwrap();
s.execute("format.color", &json!({"color": "accent2"})).unwrap();
assert_eq!(chart_of(&s, id).text_color, Some(deckcraft_model::ColorRef::scheme(deckcraft_color::SchemeSlot::Accent2)));
}