1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2025-09-13 00:06:04 +00:00

Introduce dynamic colour scheme mechanism

Also introduces palette inheritance

This finally allows us to have a palette that automatically switches between dark and light variants. The mechanism is more flexible that that, and allows for multiple colour schemes (night, morning, day, evening, for example) with automatic switching between them.
This commit is contained in:
Jeremy Ruston
2025-02-03 13:26:25 +00:00
parent a366d62358
commit 431149d20c
5 changed files with 119 additions and 49 deletions

View File

@@ -0,0 +1,13 @@
title: $:/palettes/AutoToggle
name: AutoToggle
description: Automatically switch between dark and light modes
tags: $:/tags/Palette
type: application/x-tiddler-dictionary
color-scheme: [{$:/info/browser/darkmode}match[no]then[light]else[dark]]
palette-type: classic
editor: $:/palette-editors/TwentyTwenties
palette-import@light: $:/palettes/FlexokiLight
palette-import@dark: $:/palettes/FlexokiDark
page-background@light: green
page-background@dark: red

View File

@@ -1,10 +0,0 @@
title: SampleBackgroundAction: Dark Mode
tags: $:/tags/BackgroundAction $:/tags/StartupAction/Browser
platforms: browser
track-filter: [{$:/info/browser/darkmode}]
<%if [{$:/info/browser/darkmode}match[no]] %>
<$action-setfield $tiddler="$:/palette" text="$:/palettes/TwentyTwenties"/>
<%else%>
<$action-setfield $tiddler="$:/palette" text="$:/palettes/TwentyTwenties/Dark"/>
<%endif%>

View File

@@ -1,7 +1,7 @@
title: $:/core/background-actions/AutoCompilePalette
tags: $:/tags/BackgroundAction $:/tags/StartupAction
platforms: browser
track-filter: [[$:/palette]] +[changecount[]]
track-filter: [{$:/palette}get[color-scheme]] :map[subfilter<currentTiddler>] [[$:/palette]changecount[]]
\import [subfilter{$:/core/config/GlobalImportFilter}]
<<actions-recompile-current-palette>>

View File

@@ -3,10 +3,25 @@ title: $:/snippets/currpalettepreview
\whitespace trim
\procedure colour-div-filtered(class,styleName,styleColour)
\function colour-inner-get-imported-palette(name,tv-palette-name)
[[palette-import@]addsuffix<scheme>] :map[<tv-palette-name>get<currentTiddler>has[title]] +[!match[]] :else[<tv-palette-name>get[palette-import]has[title]] :map[function[colour-inner-get-palette-entry],<name>,<currentTiddler>] +[!match[]]
\end colour-inner-get-imported-palette
\function colour-inner-get-palette-entry(name,tv-palette-name)
[<name>addprefix[@]addprefix<scheme>] :map[<tv-palette-name>getindex<currentTiddler>] +[!match[]] :else[<tv-palette-name>getindex<name>] :else[function[colour-inner-get-imported-palette],<name>,<tv-palette-name>]
\end colour-inner-get-palette-entry
<!-- Note the join, needed to cope with palette entries containing spaces -->
\function colour(name) [<colour-palette>getindex<name>] :else[<colour-palette>get[palette-import]getindex<name>] :map[subfilter<currentTiddler>join[ ]]
\function colour(name)
[function[colour-inner-get-palette-entry],<name>,<tv-palette-name>] :else[[$:/config/DefaultColourMappings/]addsuffix<name>addsuffix[@]addsuffix<scheme>get[text]] :else[[$:/config/DefaultColourMappings/]addsuffix<name>get[text]] :map[subfilter<currentTiddler>join[ ]]
\end colour
\function color(name)
[function[colour],<name>]
\end color
<$let
colour-palette=<<currentTiddler>>
colour-result={{{ [function[colour],<styleColour>] }}}
>
<div class=<<class>> style={{{ [<styleName>addsuffix[:]addsuffix<colour-result>addsuffix[;]] }}}>
@@ -19,8 +34,21 @@ title: $:/snippets/currpalettepreview
<!-- Define our own deeply backwards compatible local versions of the colour macro -->
\define colour(name)
\whitespace trim
<$transclude tiddler=<<currentTiddler>> index="$name$">
<$transclude tiddler="$:/config/DefaultColourMappings/$name$"/>
<$transclude tiddler=<<tv-palette-name>> index="$name$@$(scheme)$">
<$transclude tiddler=<<tv-palette-name>> index="$name$">
<$let
prefixed-palette-import={{{ [[palette-import@]addsuffix<scheme>] }}}
tv-palette-name={{{ [<tv-palette-name>get<prefixed-palette-import>has[title]] :else[<tv-palette-name>get[palette-import]] }}}
>
<%if [<tv-palette-name>has[title]] %>
<$transclude $variable="colour" name=<<__name__>>/>
<%else%>
<$transclude tiddler="$:/config/DefaultColourMappings/$name$@$(scheme)$">
<$transclude tiddler="$:/config/DefaultColourMappings/$name$"/>
</$transclude>
<%endif%>
</$let>
</$transclude>
</$transclude>
\end colour
\define color(name) <<colour $name$>>
@@ -33,7 +61,7 @@ title: $:/snippets/currpalettepreview
\widget $colour.div(class,styleName,styleColour)
<%if [<styleName>!match[]] %>
<%if [<currentTiddler>get[palette-type]match[modern]] %>
<%if [<tv-palette-name>get[palette-type]match[modern]] %>
<$transclude $variable="colour-div-filtered" class=<<class>> styleName=<<styleName>> styleColour=<<styleColour>>/>
<%else%>
<$transclude $variable="colour-div-wikified" class=<<class>> styleName=<<styleName>> styleColour=<<styleColour>>/>
@@ -52,9 +80,20 @@ title: $:/snippets/currpalettepreview
\end palette-preview-component-list
\procedure palette-preview-thumbnail()
<$colour.div class="tc-palette-preview-thumbnail" styleName="background-color" styleColour="page-background">
<<palette-preview-component-list "$:/tags/Preview/Page">>
</$colour.div>
<!-- Compute the scheme of the current palette -->
<$let
tv-palette-name=<<currentTiddler>>
color-scheme-filter={{{ [<tv-palette-name>get[color-scheme]] :else[[light]] }}}
scheme={{{ [subfilter<color-scheme-filter>] }}}
>
<!-- Render the thumbnail and its child components -->
<$colour.div class="tc-palette-preview-thumbnail" styleName="background-color" styleColour="page-background">
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Preview/Page]!has[draft.of]]" variable="componentTitle">
<$transclude $tiddler=<<componentTitle>> title=<<title>>/>
</$list>
</$colour.div>
</$let>
\end palette-preview-thumbnail
<!-- currentTiddler is the palette to use -->
<<palette-preview-thumbnail>>

View File

@@ -1,43 +1,60 @@
title: $:/core/macros/CSS
tags: $:/tags/Macro
\procedure actions-compile-palette-filtered(tempPalette,outputTitle)
\procedure actions-compile-palette-filtered(tempPalette,outputTitle,scheme)
<!-- Note the join, needed to cope with palette entries containing spaces -->
\function colour(name) [<tempPalette>getindex<name>] :else[[$:/config/DefaultColourMappings/]addsuffix<name>get[text]] :map[subfilter<currentTiddler>join[ ]]
\function colour(name) [<name>addsuffix[@]addsuffix<scheme>] :map[<tempPalette>getindex<currentTiddler>] +[!match[]] :else[<tempPalette>getindex<name>] :else[[$:/config/DefaultColourMappings/]addsuffix<name>addsuffix[@]addsuffix<scheme>get[text]] :else[[$:/config/DefaultColourMappings/]addsuffix<name>get[text]] :map[subfilter<currentTiddler>join[ ]]
\function color(name) [function[colour],<name>]
<!-- Make the colour function use the input palette -->
<$list filter="[<tempPalette>indexes[]sort[]]" variable="colour-name">
<$let colour-filter={{{ [<tempPalette>getindex<colour-name>] }}}>
<$let filter-text={{{ [<colour-name>addsuffix[@]addsuffix<scheme>] :map[<tempPalette>getindex<currentTiddler>] +[!match[]] :else[<tempPalette>getindex<colour-name>] :else[[$:/config/DefaultColourMappings/]addsuffix<colour-name>addsuffix[@]addsuffix<scheme>get[text]] :else[[$:/config/DefaultColourMappings/]addsuffix<colour-name>get[text]] }}}>
<!-- Note the join, needed to cope with palette entries containing spaces -->
<$action-setfield $tiddler=<<outputTitle>> $index=<<colour-name>> $value={{{ [subfilter<colour-filter>join[ ]] }}}/>
<$action-setfield $tiddler=<<outputTitle>> $index=<<colour-name>> $value={{{ [subfilter<filter-text>join[ ]] }}}/>
</$let>
</$list>
\end actions-compile-palette-filtered
\procedure actions-compile-palette-wikified(tempPalette,outputTitle)
\procedure actions-compile-palette-wikified(tempPalette,outputTitle,scheme)
<!-- Define our own deeply backwards compatible local versions of the colour macro -->
\define colour(name)
\whitespace trim
<$transclude tiddler=<<tempPalette>> index="$name$">
<$transclude tiddler="$:/config/DefaultColourMappings/$name$"/>
<$transclude tiddler=<<tempPalette>> index="$name$@$(scheme)$">
<$transclude tiddler=<<tempPalette>> index="$name$">
<$transclude tiddler="$:/config/DefaultColourMappings/$name$@$(scheme)$">
<$transclude tiddler="$:/config/DefaultColourMappings/$name$"/>
</$transclude>
</$transclude>
</$transclude>
\end colour
\define color(name) <<colour $name$>>
<$list filter="[<tempPalette>indexes[]sort[]]" variable="colour-name" $debug="yes">
<$wikify name="colour-value" text={{{ [<tempPalette>getindex<colour-name>] }}} mode="inline">
<$action-setfield $tiddler=<<outputTitle>> $index=<<colour-name>> $value=<<colour-value>>/>
</$wikify>
<$let
palette-entry-text={{{ [<colour-name>addsuffix[@]addsuffix<scheme>] :map[<tempPalette>getindex<currentTiddler>] +[!match[]] :else[<tempPalette>getindex<colour-name>] :else[[$:/config/DefaultColourMappings/]addsuffix<colour-name>get[text]] }}}
>
<$wikify name="colour-value" text=<<palette-entry-text>> mode="inline">
<$action-setfield $tiddler=<<outputTitle>> $index=<<colour-name>> $value=<<colour-value>>/>
</$wikify>
</$let>
</$list>
\end actions-compile-palette-wikified
\procedure actions-compile-palette-import(inputTitle,outputTitle,exclusions:"")
\procedure actions-compile-palette-import(inputTitle,outputTitle,exclusions:"",scheme)
<$action-log $message="Inside actions-compile-palette-import" inputTitle=<<inputTitle>> outputTitle=<<outputTitle>> exclusions=<<exclusions>> scheme=<<scheme>>/>
<%if [enlist<exclusions>!match<inputTitle>count[]] :map[enlist<exclusions>count[]compare:number:eq<currentTiddler>] +[!match[]] %>
<$set name="exclusions" filter="[enlist<exclusions>] [<inputTitle>]">
<%if [<inputTitle>get[palette-import]has[title]] %>
<$transclude $variable="actions-compile-palette-import" inputTitle={{{ [<inputTitle>get[palette-import]] }}} outputTitle=<<outputTitle>> exclusions=<<exclusions>>/>
<%endif%>
<$list filter="[<inputTitle>indexes[]sort[]]" variable="colour-name">
<$action-setfield $tiddler=<<outputTitle>> $index=<<colour-name>> $value={{{ [<inputTitle>getindex<colour-name>] }}}/>
</$list>
<$let
prefixed-palette-import={{{ [[palette-import@]addsuffix<scheme>] }}}
inputTitle={{{ [<inputTitle>get<prefixed-palette-import>has[title]] :else[<inputTitle>get[palette-import]] }}}
>
<%if [<inputTitle>has[title]] %>
<$transclude $variable="actions-compile-palette-import" inputTitle=<<inputTitle>> outputTitle=<<outputTitle>> exclusions=<<exclusions>> scheme=<<scheme>>/>
<%endif%>
</$let>
<$action-log $message="Back in actions-compile-palette-import" inputTitle=<<inputTitle>> outputTitle=<<outputTitle>> exclusions=<<exclusions>> scheme=<<scheme>>/>
<$action-log $tiddler=<<outputTitle>> $indexes={{{ [<inputTitle>indexes[]sort[]] +[join[,]] }}} $values={{{ [<inputTitle>indexes[]sort[]] :map[<inputTitle>getindex<currentTiddler>] +[join[,]] }}}/>
<$action-setmultiplefields $tiddler=<<outputTitle>> $indexes="[<inputTitle>indexes[]sort[]]" $values="[<inputTitle>indexes[]sort[]] :map[<inputTitle>getindex<currentTiddler>]"/>
<$action-log $tiddler=<<outputTitle>> $fields={{{ [<inputTitle>fields[]sort[]] -title -tags -text +[join[,]] }}} $values={{{ [<inputTitle>fields[]sort[]] -title -tags -text :map[<inputTitle>get<currentTiddler>] +[join[,]] }}}/>
<$action-setmultiplefields $tiddler=<<outputTitle>> $fields="[<inputTitle>fields[]sort[]] -title -tags -text" $values="[<inputTitle>fields[]sort[]] -title -tags -text :map[<inputTitle>get<currentTiddler>]"/>
</$set>
<%endif%>
\end actions-compile-palette-import
@@ -47,18 +64,29 @@ tags: $:/tags/Macro
<$let
tempPalette="$:/temp/palette-consolidated"
>
<!-- Clear the temporary consolidated palette -->
<$action-deletetiddler $tiddler=<<tempPalette>>/>
<!-- Consolidate the chain of palettes -->
<$transclude $variable="actions-compile-palette-import" inputTitle=<<inputTitle>> outputTitle=<<tempPalette>>/>
<!-- Compile the temporary palette to the output palette -->
<%if [<inputTitle>get[palette-type]match[modern]] %>
<$transclude $variable="actions-compile-palette-filtered" tempPalette=<<tempPalette>> outputTitle=<<outputTitle>>/>
<%else%>
<$transclude $variable="actions-compile-palette-wikified" tempPalette=<<tempPalette>> outputTitle=<<outputTitle>>/>
<%endif%>
<!-- Remove the temporary consolidated palette -->
<!-- <$action-deletetiddler $tiddler=<<tempPalette>>/> -->
<!-- Compute the current scheme -->
<$let
color-scheme-filter={{{ [<inputTitle>get[color-scheme]] :else[[light]] }}}
scheme={{{ [subfilter<color-scheme-filter>] }}}
>
<!-- Clear the temporary consolidated palette -->
<$action-deletetiddler $tiddler=<<tempPalette>>/>
<$action-setfield $tiddler=<<tempPalette>> type="application/x-tiddler-dictionary"/>
<$action-deletetiddler $tiddler=<<outputTitle>>/>
<$action-setfield $tiddler=<<outputTitle>> type="application/x-tiddler-dictionary"/>
<!-- Consolidate the chain of palettes -->
<$transclude $variable="actions-compile-palette-import" inputTitle=<<inputTitle>> outputTitle=<<tempPalette>> scheme=<<scheme>>/>
<!-- Clear the output palette and assign the scheme -->
<$action-setfield $tiddler=<<outputTitle>> $field="color-scheme" $value=<<scheme>>/>
<!-- Compile the temporary palette to the output palette -->
<%if [<inputTitle>get[palette-type]match[modern]] %>
<$transclude $variable="actions-compile-palette-filtered" tempPalette=<<tempPalette>> outputTitle=<<outputTitle>> scheme=<<scheme>>/>
<%else%>
<$transclude $variable="actions-compile-palette-wikified" tempPalette=<<tempPalette>> outputTitle=<<outputTitle>> scheme=<<scheme>>/>
<%endif%>
<!-- Remove the temporary consolidated palette -->
<!-- <$action-deletetiddler $tiddler=<<tempPalette>>/> -->
</$let>
</$let>
\end actions-compile-palette
@@ -76,7 +104,7 @@ tags: $:/tags/Macro
\procedure tv-palette-name() $:/temp/palette-colours
\function colour(name)
[<tv-palette-name>getindex<name>] :else[[$:/config/DefaultColourMappings/]addsuffix<name>get[text]]
[<tv-palette-name>get[colour-scheme]addprefix[@]addprefix<name>] :map[<tv-palette-name>getindex<currentTiddler>] +[!match[]] :else[<tv-palette-name>getindex<name>] :else[[$:/config/DefaultColourMappings/]addsuffix<name>get[text]]
\end colour
\function color(name)