Accessing row contents from Style API

Hello!

I’m currently using Bike 2’s extension-kit to bodge together an org-mode style todo system with scheduled dates. I’d like to add a little chip to tasks that have a scheduled date attribute attached, so I’ve been using the Style API to do this. I was curious if there’s some way to get the value of a row’s attribute within Style API calls, e.g.

mod.layer("base", (row, run, caret, viewport, include) => {
  row(`.@type = task and @scheduledStart`, (context, row) => {
    row.decoration("todo-chip", (mark, layout) => {
      const text = // Some function call to get the value of @scheduledStart here
      mark.contents.gravity = "right";
      mark.contents.image = Image.fromText(new Text(text));
    });
  });
});

Sorry, but that’s not possible. They style system relies on lot of caching to be performant and row state isn’t factored into those caches, so can’t be exposed in the style functions.

Edit Post 2.0 release I will be investigating “tags” system which I think will allow you to do what you want. I think it will be a TaskPaper style tags system where tags have optional value. And they are both displayed in row text.

2 Likes

Gotcha, thanks for the heads up! As a note, I was able to bodge something that pretends to do row attribute-dependent styling by bodging outline queries (generating a styling rule for every month and every day in a month, etc.) and taking advantage of the fact that mark properties (specifically, the mark.contents.gravity property) are persisted across queries:

mod.layer("base", (row, run, caret, viewport, include) => {  
  for (let month = 1; month <= 12; month++) {
    const monthTxt = month.toString().padStart(2, "0");
    row(`.@scheduledStart contains "-${monthTxt}-"`, (context, row) => {
      row.decoration("todo-chip", (mark, layout) => {
        // @ts-ignore
        mark.contents.gravity = textForMonth(month);
      });
    });
  }

  for (let day = 1; day <= 31; day++) {
    const dayTxt = day.toString().padStart(2, "0");
    row(
      `.@scheduledStart contains "-${dayTxt}T"`,
      (context, row) => {
        row.decoration("todo-chip", (mark, layout) => {
          mark.contents.image = Image.fromText(
            // @ts-ignore
            new Text(mark.contents.gravity + " " + day),
          );
          mark.contents.gravity = "right";
        });
      },
    );
  }
}

This code will produce something like the following when a @scheduledStart Date attribute is attached to an item:

I imagine this wasn’t the intended use of these features though, and I’m not sure doing this will create performance or correctness bugs down the line :slight_smile:

Yes, and no. At a high level this is how queries/styling is designed to work. So you aren’t breaking any rules. Question is just if you eventually have too many queries and that makes things slow. I’m glad to hear that it’s at least not immediately obvious that things are slow… that’s definitely more queries then I’ve tested with :slight_smile: