Idea to fix the color field from always showing black

Edit: I’ve marked this as solved ref to a css hack I made, but in this thread Eric also presents a significantly more ambitious solution. Of course, the real hope is that this bug should be properly solved for the core.


Question: The bug with the color fields always showing “black” regardless of set color - is this due to some backward break conflict? Is 5.4.0 the opportunity to fix it?

(…because that is not only a problem on my machines, right? This bug has been persistent forver I think)

The HTML standard type=color input control only displays the selected color if it has been specified using a 6-digit hex #RRGGBB value. This is not a problem if you ONLY use the type=color control to select a color. However, if you have some other method of setting the color (e.g. directly in tiddler content or from a ViewTemplate) that does not use type=color, such as

<$edit-text type="text" field="color"/>

then you can enter colors using any valid CSS format, including:

  • 3-, 4-, or 8-digit hex = #RGB or #RGBA or #RRGGBBAA
  • decimal RGB values = rgb(255,255,255) or rgba(255,255,255,255)
  • X11 color names = “red”, “green”, “blue”, “cyan”, etc.

These color values will still be applied when rendering the tiddler, but… since they don’t conform to the 6-digit hex values supported by the type=color HTML input, they show as black for the color control in the tiddler editor.

I’ve written code that solves this problem by converting the above color value formats to 6-digit hex, but it is not trivial, and probably won’t ever make it into the TWCore. See TiddlyTools/Palettes/Manager. Specifically, this macro:

\define palette-manager-colour-pick(field,index,tip)
\define hex(n) ^#[A-Fa-f0-9]{$n$}$
<!-- GET #RRGGBB FROM MACRO/WIDGET VALUE, MATCHNG X11 NAMES, EXPAND #RGBA, CONVERT RGBA() -->
<$let id={{{ [<__index__>!match[]] ~[<__field__>] }}} c={{{ [<currentTiddler>getindex<id>] ~[<currentTiddler>get<id>] }}}>
<$wikify name=v text=<<c>>>
<$let
	c={{{ [<c>prefix[#]] ~[<v>] }}}
	c={{{ [<X11Colors>indexes[]match:caseinsensitive<c>] :map[<X11Colors>getindex<currentTiddler>] ~[<c>] }}}
	c={{{ [<c>regexp<hex 3,4>split[]!match[#]] :map[<currentTiddler>addsuffix<currentTiddler>] +[join[]!match[]addprefix[#]] ~[<c>] }}}
	a={{{ [<c>regexp<hex 8>split[]last[2]join[]] }}}
	c={{{ [<c>regexp<hex 8>split[]first[7]join[]] ~[<c>] }}}
	d={{{ [<c>lowercase[]prefix[rgb]split[(]nth[2]trim[)]split[,]join[ ]] }}}
	d={{{ [enlist:raw<d>first[3]]		=[enlist:raw<d>nth[4]!match[]multiply[255]trunc[]]	+[join[ ]] }}}
   hi={{{ [enlist:raw<d>divide[16]]		:map[[0123456789abcdef]split[]zth<currentTiddler>]	+[join[ ]] }}}
   lo={{{ [enlist:raw<d>remainder[16]]	:map[[0123456789abcdef]split[]zth<currentTiddler>]	+[join[ ]] }}}
	r={{{ [enlist:raw<hi>nth[1]] =[enlist:raw<lo>nth[1]] +[join[]] }}}
	g={{{ [enlist:raw<hi>nth[2]] =[enlist:raw<lo>nth[2]] +[join[]] }}}
	b={{{ [enlist:raw<hi>nth[3]] =[enlist:raw<lo>nth[3]] +[join[]] }}}
	a={{{ [enlist:raw<hi>nth[4]] =[enlist:raw<lo>nth[4]] +[join[]] ~[<a>] }}}
	c={{{ [<r>] =[<g>] =[<b>] +[join[]!match[]addprefix[#]] ~[<c>] }}}>
<$eventcatcher stopPropagation=never $focusin="<$action-deletetiddler $tiddler=<<pick>>/>"
	 $change="<$action-setfield $field=<<__field__>> $index=<<__index__>> $value={{{ [<pick>getindex<id>] [<a>] +[join[]] }}}/><$action-deletetiddler $tiddler=<<pick>>/>">
<span title={{{ [[pick a color for]] [<__tip__>] +[join[ ]] }}}>
<$edit-text tiddler=<<pick>> index=<<id>> tag=input type=color default=<<c>> class={{{ [[tt-palettemanager-colourpick tc-popup-handle]] [<id>] +[join[ ]] }}}/>
\end

Note that <X11Colors> is a reference to a separate tiddler (TiddlyTools/Settings/Colors/X11), which is a DataDictionary tiddler that contains 151 color name indexes with their corresponding #RRGGBB color values. If this tiddler is not present, the reference to it just “falls through” without changing the computed color value (<c>).

For general info on X11 color names, see X11 color names - Wikipedia

enjoy,
-e

2 Likes

I probably don’t understand you full answer but, regardless, rather than falling back on showing as black, do you think it could be made to instead fall back on showing the user set value? E.g showing the literal value e.g the word “red”?

Somewhere deep in a very complex chain of TWCore code that I’ve not yet located, it detects that the field name is “color”, and defaults to using the type="color" attribute to show the HTML color input control. Thus,

<$edit-text field="color"/>

shows the HTML color input control, while

<$edit-text type="text" field="color"/>

forces it to show a regular text input control.

Once the relevant code is identified, I suppose it would be relatively simple to detect if the field value conforms to the #RRGGBB format, and if it doesn’t then don’t use type="color", and let the default or explicitly specified type handling apply.

-e

We probably could create a field-editor cascade rule, that checks for a valid colour definition and if it is not #RRGGBB, that the browser colour-pickers understand we could show the “raw value” instead.

Or we implement Erics fix – That’s possible too – But if users use that colour-picker, other values would be overwritten with RGB – Not sure what’s the best way to go.

@EricShulman @Mario - is this relevant for the OP or should I attempt to split this out? I.e is it a matter about breaking backwards compat?

We could also just show both the “raw value” AND the color picker, which is what the TWCore’s $:/PaletteManager and TiddlyTools/Palettes/Manager does.

Note that the TWCore $:/PaletteManager color picker shows black if the color value isn’t #RRGGBB format, but my enhanced TiddlyTools/Palettes/Manager does the conversion I described above.

I don’t think this is a TW5.4.0 “breaking change” issue, and it might be a good idea to split it off from this thread.

-e

Right! The color field could simply display a combo box for direct typing and with the colopicker as dropdown. Next to it, there’s a simple div showing the background:{{!!color}} - super simple! Why didn’t we do this a decade ago!?

Give this a try: TiddlyTools/Templates/Color

It provides an alternative to the TWCore’s handling for “color” fields in the Tiddler Editor.

  • Shows regular text input for entering color with example color “swatch” next to it (to see actual color).
  • Handles ALL valid CSS color values including 3-, 4-, 6-, 8-digit hex, rgb(…), rgba(…), or X11 color names.
  • If TiddlyTools/Settings/Colors/X11 Data Dictionary tiddler is present, a dropdown list of X11 colors is also shown with “progressive search” to filter list for matching color names (e.g., if you type “blue”, it will list only those X11 color names that contain “blue”).

enjoy,
-e

Neat! Great dropdown when using that X11. How about letting the regular color picker appear as a fallback if there is no X11?

Just so no misunderstanding: I’m raising the OP with the hope of this “black bug” being corrected in the core, not really for a personal need (even if the bug does persistently annoy me).

You said you didn’t think the previous solution you posted would ever make it into the core; Would that be because of the X11 parts? If it is the regular color picker, do you think that would be accepted? I think it makes sense with a core solution for this bug.


Addition after having now played with the X11 more: Dang, it’s just really nice with them named colurs. It makes things feel more served than when color-picking from a gradient, and of course it is much easier to remember named colors.

Does this happen to be a smaller solution than the regular color picker? If it is, I wouldn’t mind having the regular color picker externalized into a plugin, and the named colors as standard instead. I guess that would make it a 5.4.0 proposal after all.

Done. TiddlyTools/Templates/Color now includes a fallback to use the TWCore <<colour-picker>> macro if TiddlyTools/Settings/Colors/X11 is missing.

The X11 color mapping is just one line in the TiddlyTools/Palettes/Manager palette-manager-colour-pick() macro. It’s the rest of that macro code that MIGHT be too much for the TWCore.

-e

1 Like

TiddlyTools/Settings/Colors/X11 is somewhat larger than the TWCore’s <<colour-picker>> list for several reasons that help increase the utility of TiddlyTools/Settings/Colors/X11 in a variety of circumstances:

  • TiddlyTools/Settings/Colors/X11 is stored as a separate DataDictionary tiddler, while the TWCore list is hard-coded directly as a $list widget filter="..." parameter in the <<colour-picker>> macro. Using a DataDictionary allows the color names to be readily available for other purposes via [[TiddlyTools/Settings/Colors/X11]indexes[]] filter syntax.

  • Each color index entry in TiddlyTools/Settings/Colors/X11 includes the corresponding #RRGGBB value so any given color name can be easily converted to its equivalent hex code via [[TiddlyTools/Settings/Colors/X11]getindex[ColorNameHere]] filter syntax.

  • TiddlyTools/Settings/Colors/X11 also contains a custom dark field that identifies a list of specific color names for which a light text color will provide better contrast when shown on top of that background color. For example, I use this list in TiddlyTools/Templates/Color via {{{ [<X11>get[dark]enlist-input[]match<c>then[white]else[black]] }}} to set the option text color for better readability of each $select list item

-e

Update:

I’ve just added support for handling #RRGGBB color conversion to TiddlyTools/Templates/Color so that clicking on the color “swatch” next to the color text input field will invoke a standard system-provided color picker popup interface that shows the correct color for any valid CSS color syntax (3-, 4-, 6-, 8-digit hex, rgb(…), rgba(…), or X11 color names).

Note that mapping X11 color names to #RRGGBB values requires installing the TiddlyTools/Settings/Colors/X11 DataDictionary tiddler; otherwise, the color swatch/picker will still display a fallback to black.

In addition to supporting ALL the various CSS color syntax formats, the “swatch” control also handles TWCore <<color ...>> macros (such as <<color dirty-indicator>>). However, this does NOT guarantee that entering a color macro into a tiddler’s {{!!color}} field will be properly displayed in all places that reference that field, since the field value still needs to be wikified by those references in order to get the underlying palette color definition.

enjoy,
-e

Great stuff @EricShulman

I made this wiki for me - or anyone - to test your creation.

[edit see msg from Thomas below] There seems to be a bug though; ironically the very bug in the OP about the colourpicker only showing black! I’m guessing that is why the opened colourpicker also doesn’t actually pinpoint the set colour?


On a very related note, I posted this Issue on gh. Therein I explain an idea for an even simpler UI; have the edit field itself have the background of the selected colour! I think this is the probably most elegant solution, perhaps also for your creation?

BTW, in the posted gh issue I did not bring up the named dropdown idea because that would be a matter for a separate post. And before that, a step on the way that also seems obvious, would be to have those hard coded named colors in the colour-picker macro extracted into a separate tiddler. That would open up for X11 as a plugin but also generally more hackability.

In fact your wiki is working fine it’s just that the name of the color needs to be spelled with a capital B “Blue” to match the X11 dictionary. And then the color swach acts correctly.

Doh! Haha, thanks!

Thanks for finding this! It’s been fixed, and the X11 dictionary lookup is now case-insensitive. You can enter “Blue”, “blue”, “BLUE” or even “bLuE”, and they will all retrieve the correct #RRGGBB value.

-e

1 Like

I previously did some experiments with this. However, I found that it can result in poor readability due to lack of contrast between the edit field text and background colors, and also depends upon what the current color $:/palette settings are for tiddler-controls-foreground and tiddler-editor-background. In addition, the color “swatch” is still needed in order to permit a type=color popup that shows a system-provided standard “color picker” interface.

-e

Tags themselves solve this with automatic contrasting colours. Now they do depend on the selected palette, but I figure that if someone finds a palette to their satisfaction then who am I to argue with that…