Skip to content

Colour handling improvements#8702

Open
Jermolene wants to merge 217 commits intomasterfrom
colour-improvements
Open

Colour handling improvements#8702
Jermolene wants to merge 217 commits intomasterfrom
colour-improvements

Conversation

@Jermolene
Copy link
Member

@Jermolene Jermolene commented Oct 25, 2024

UPDATE 6th FEBRUARY 2026

After some discussion, this PR is now deferred to v5.5.0 to give more time to iron out some details. In the meantime, background actions, filter tracking and media query tracking have been cherrypicked into #9641 so that they can be included in v5.4.0.

Introduction

This PR brings several new features for end users:

  • Automatically switching between a dark and light palette as the operating system setting changes (and to do so without making the wiki dirty)
  • Customisation options for palettes. For example, users might choose a base hue, with the colours of the palette automatically adapting to it
  • A generalisation of the dark vs. light mechanism to allow an arbitrary number of distinct schemes that are dynamically selected. For example, a palette that has a different scheme for night, morning, day and evening that automatically change with the time of day

There are also new capabilities for palette authors:

  • Inheritance for palettes, making it easy to create chains of variants of a base palette
  • Self contained palettes that can contain both dark and light variants (or variants for any other custom scheme)

To make all of these new features possible, this PR also includes some useful new general purpose mechanisms and features:

  • Background actions that are triggered whenever there is a change to the results of a specified filter
  • Several new filter operators for manipulating colour values. The underlying functionality comes from the color.js library
  • New media query tracking mechanism that can track the results of any CSS media query (not just dark mode), storing the results in a shadow $:/info/... tiddler
  • New changecount filter operator
  • New :apply filter run prefix

Try the Demo

A preview build is available at https://deploy-preview-8702--tiddlywiki-previews.netlify.app/

image

Changes to Palettes

Palette entries are now defined as filters that must be evaluated, rather than wikitext that must be wikified.

This makes it possible to create palettes that reference and modify other colours. For example:

tiddler-controls-foreground-selected: [tf.interpolate-colours[background],[foreground],[0.9]]

Retrospectively re-interpreting palettes entries as filters would normally mean that <<colour background>> would no longer work. Instead these entries are automatically converted to the updated form [function[colour],[background]].

Palette Compilation

The key idea underpinning these changes is a fundamental change to the way that TiddlyWiki handles palettes. At the moment, palette entries are named items that can contain either a CSS colour string, a CSS colour token like "inherit", or can use the <<colour>> macro to reference another colour palette entry. Thus, palette entries have to be wikified before they can be used. This has turned out to be very limiting and doesn't provide a viable path to the complex colour manipulations shown above. Switching to filters might make things worse, by encouraging authors to use complex expressions within palettes.

The fix is compiled palettes: at the point of switching to a new palette, the colours within it are "compiled" to raw CSS colour values (typically but not necessarily in #rrggbbaa format). This allows palette entries to be used directly, without the requirement to wikify them.

The static palette is created in a new system tiddler $:/temp/palette-colours by an action procedure that is invoked at startup and when switching to a new palette.

There should not be any backwards compatibility issues because the use of background actions means that any code that changes $:/palette will automatically trigger the recompilation of the palette.

This change also allows us to change the <<colour>> procedure to be a function, which allows it to be used as the value for a style attribute:

<div style.background=<<colour tiddler-background>>>

Automatic Palette Readability Tests

Palettes can opt to include readability tests as special palette entries. The results of these tests are shown at the bottom of the palette chooser. For example:

?base-background-ink: [tf.check-colour-contrast[base-background],[base-ink],[45]]

The test framework looks for palette entries starting with a question mark and runs the associated filters. The filter should return nothing if there are no errors, or a textual error message if the conditions are violated. Sample output:

alert-contrast: 42.357: alert-background/foreground contrast is too low
background-foreground-contrast: 41.915: background/foreground contrast is too low
base-ink-secondary: 42.357: base-ink/base-secondary contrast is too low
base-paper-ink: 41.915: base-paper/base-ink contrast is too low
base-paper-primary: 32.682: base-paper/base-primary contrast is too low
base-paper-tertiary: 30.502: base-paper/base-tertiary contrast is too low
code-contrast: 28.565: code-background/code-foreground contrast is too low

Colour Manipulation

We need a colour manipulation library that can calculate variants of colours. Only color.js met the requirements of being able to work with P3 colours and the OKLCH colour space. It also includes a CSS colour string parser which can replace the simple one that TiddlyWiki has always incorporated.

Media Query Tracker

The CSS media query tracker allows a media query to be bound to an info tiddler so that the current state of the query is reflected in the value of the tiddler. The value is updated dynamically.

The use of the info mechanism for the CSS media query tracker means that these tiddlers are dynamically created as shadow tiddlers within the $:/temp/info plugin, and so do not appear in tiddler lists.

The mechanism is used to implement the existing dark mode tiddler with the following configuration:

title: $:/core/wiki/config/MediaQueryTrackers/DarkLightSwitch
tags: $:/tags/MediaQueryTracker
media-query: (prefers-color-scheme: dark)
info-tiddler: $:/info/browser/darkmode
info-tiddler-alt: $:/info/darkmode

Note the use of info-tiddler-alt to specify a redundant secondary info tiddler. This is used by the dark mode tracker to maintain compatibility while changing the info tiddler title for consistency.

Background Actions

The new background actions mechanism allows action strings to be invoked automatically in the background whenever the results of a filter change.

The preview includes a demonstration background action that displays an alert with a list of tiddlers in the story river whenever the story river changes:

title: SampleBackgroundAction: Story Change
tags: $:/tags/BackgroundAction
track-filter: [list[$:/StoryList]]

<$action-sendmessage $message="tm-notify" $param="SampleBackgroundAction: Story Change" list={{$:/StoryList!!list}}/>

Story List:

<ol>
<$list filter="[enlist<list>]">
<li>
<$text text=<<currentTiddler>>/>
</li>
</$list>
</ol>

apply Filter Run Prefix

An experimental new filter run prefix that makes it possible to use computed values as variables within a filter run. For example:

\function tf.interpolate-colours(paletteEntryA,paletteEntryB,weight)
[function[colour],<paletteEntryA>] [function[colour],<paletteEntryB>] :apply[<weight>colour-interpolate:oklch<$1>,<$2>]
\end tf.interpolate-colours

Backwards Compatibility

  • The current content of $:/PaletteManager is moved into $:/PaletteEditor, and $:/PaletteManager repurposed as the control panel palette switcher
  • $:/config/DefaultColourMappings/ now only supports CSS colours, and not indirections via <<colour X>> or [function[colour],[X]]

References

Progress

  • Documentation
    • Palettes and colour schemes
    • Background palettes (which should probably be renamed!)
    • Media Query Tracker
    • Background actions
    • changecount operator
    • colour-interpolate operator
    • colour-lighten operator
    • colour-darken operator
    • colour-get-oklch operator
    • colour-set-oklch operator
    • colour-contrast operator
    • colour-best-contrast operator
    • Adopt palettes from https://yatagarasu.tiddlyhost.com/
  • Background Actions
    • Explore supporting long running asynchronous background tasks (v5.5.0)

The replacement library from https://colorjs.io/ is much, much larger but I think we can develop a custom build that uses treeshaking to whittle the code down to the bits that we need. @linonetwo does that sound feasible?

I intend the explore further improvements but I wanted to start by establishing a library that can do modern P3 and OKLCH colour calculations.
Really just syntactic sugar for the wikify widget
Using the new wikify operator.

Currently has a bug whereby redirected colours (like "tiddler-background") do not work. Direct colours like "background" do work.

Note the hacks needed to makeFakeWidgetWithVariables work
@github-actions
Copy link

Confirmed: Jermolene has already signed the Contributor License Agreement (see contributing.md)

@kookma
Copy link
Contributor

kookma commented Nov 4, 2024

Is there a demo to test colour handling improvement?

@Jermolene
Copy link
Member Author

Is there a demo to test colour handling improvement?

Hi @kookma I've posted a preview to tiddlyhost

@TiddlyWiki TiddlyWiki deleted a comment from github-actions bot Jan 22, 2026
@TiddlyWiki TiddlyWiki deleted a comment from github-actions bot Jan 22, 2026
@TiddlyWiki TiddlyWiki deleted a comment from github-actions bot Jan 22, 2026
@TiddlyWiki TiddlyWiki deleted a comment from github-actions bot Jan 22, 2026
@TiddlyWiki TiddlyWiki deleted a comment from github-actions bot Jan 22, 2026
@github-actions
Copy link

✅ Change Note Status

All change notes are properly formatted and validated!

📝 $:/changenotes/5.4.0/#8702

Type: enhancement | Category: hackability
Release: 5.4.0

Colour handling improvements

🔗 #8702

👥 Contributors: Jermolene


📖 Change Note Guidelines

Change notes help track and communicate changes effectively. See the full documentation for details.

@github-actions
Copy link

📊 Build Size Comparison: empty.html

Branch Size
Base (master) 2448.0 KB
PR 2459.3 KB

Diff: ⬆️ Increase: +11.3 KB

@TiddlyWiki TiddlyWiki deleted a comment from github-actions bot Feb 2, 2026
@TiddlyWiki TiddlyWiki deleted a comment from github-actions bot Feb 2, 2026
@Leilei332
Copy link
Contributor

Leilei332 commented Feb 3, 2026

I'm afraid that this PR may be too huge to be completed before 6th Feb. I think we may split these features to be included in v5.4.0:

  • media query tracker
  • apply filter run prefix

@Jermolene
Copy link
Member Author

I'm afraid that this PR may be too huge to be completed before 6th Feb. I think we may split these features to be included in v5.4.0:

  • media query tracker
  • apply filter run prefix

I concur. I was planning to drop the apply filter run prefix in favour of the new let prefix. The media tracker stuff will also bring the general background task mechanism. I'll post a PR soon.

@saqimtiaz saqimtiaz moved this from Ready to In progress in Planning for v5.4.0 Feb 4, 2026
@github-actions
Copy link

github-actions bot commented Feb 6, 2026

✅ Change Note Status

All change notes are properly formatted and validated!

⚠️ Impact: $:/changenotes/5.4.0/#8702/impacts/wikitext-palette-entries

Impact Type: deprecation
Related Change: $:/changenotes/5.4.0/#8702

Palette entries using wikification will no longer work


📖 Change Note Guidelines

Change notes help track and communicate changes effectively. See the full documentation for details.

@github-actions
Copy link

github-actions bot commented Feb 6, 2026

📊 Build Size Comparison: empty.html

Branch Size
Base (master) 2448.0 KB
PR 2458.6 KB

Diff: ⬆️ Increase: +10.6 KB

Jermolene added a commit that referenced this pull request Feb 6, 2026
Jermolene added a commit that referenced this pull request Feb 6, 2026
...which need to also be turned into a changenote
@saqimtiaz saqimtiaz moved this to In progress in Planning for v5.5.0 Feb 6, 2026
Jermolene added a commit that referenced this pull request Feb 6, 2026
* Initial commit cherry picked from #8702

* Initial docs from #8702

...which need to also be turned into a changenote

* Add changenote
@Jermolene Jermolene mentioned this pull request Feb 11, 2026
4 tasks
Jermolene added a commit that referenced this pull request Feb 20, 2026
Jermolene added a commit that referenced this pull request Feb 20, 2026
* Tweak some changenotes

* Tweak release note tabs

* Simplify summary tab

* Remove #8702 changes/impacts

* Search change notes and impacts

* Fix release note category search

* Tweak headline changenotes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

8 participants