congo icon indicating copy to clipboard operation
congo copied to clipboard

:children_crossing: Add POC implementation of divineRGBVal

Open wolfspyre opened this issue 1 year ago • 9 comments

:children_crossing: :technologist: :wrench: :adhesive_bandage: DivineRGBVal

This is an initial stab at providing a server-side mechanism of determining the RGB values of tailwind-style colors.

I'm okay with it as is, but I'm totally open to adjusting the implementation if desired.

This adds two json datafiles:

  • data/congo.json This provides an in-scope lookup table to facilitate resolution of the tailwind color names abstracted into primary secondary and neutral per color-scheme; and default shade/weight values.

  • data/twcolormap.json This is the datasource actually referenced by the partial to return values to the calling entity.

It can likely be improved substantially, but I wanted to get it visible and get a conversation going before trying to perfect it.

I see this as a server-side replacement for the voodoo of appearance.js manipulating the color value of metatags client-side.

The partial is overly verbose if the debug variable is set to true, MOSTLY for the purposes of illustrating what was being done and why...

Here's the log output from me having the partial partials/favicons.html invoke this partial to determine the primary colorvalue for the site: relevant snippit from partials/favicons.html:

{{- $favItch     :=            newScratch -}}
{{- $favItch.Set "logPrefix"   "[partials/favicons.html] " -}}
{{- $favItch.Set "debugPrefix" (print "[DEBUG]" ( $favItch.Get "logPrefix" )) -}}

{{- $priCol := (partial "util/divineRGBVal.html" (dict "context" . "color" "primary"  )) -}}
{{- warnf "%s - divineRGB: %s " ( $favItch.Get "logPrefix" ) $priCol  -}}

Log output:

WARN  [DEBUG][partials/favicons.html]  Debug Enabled
WARN  [DEBUG][util/divineRGBVal.html]  Debug enabled
WARN  [DEBUG][util/divineRGBVal.html]  ..-. Theme colorScheme not provided on invocation. Read 'avocado' from site.Params.colorScheme.
WARN  [DEBUG][util/divineRGBVal.html]  +... Color given: primary
WARN  [DEBUG][util/divineRGBVal.html]  --.. Color 'primary' doesn't seem to be a tailwind-style (color)-(shade) combo.
WARN  [DEBUG][util/divineRGBVal.html]  -.-. Color 'primary' references a theme-abstracted value. Further divination required
WARN  [DEBUG][util/divineRGBVal.html]  .--. Desired Shade unknown. Will lookup theme-value default for primary
WARN  [DEBUG][util/divineRGBVal.html]  .+.. Desired Shade: primary
WARN  [DEBUG][util/divineRGBVal.html]  .--? Shade not provided on invocation. Determining fallback value for 'primary'.
WARN  [DEBUG][util/divineRGBVal.html]  .--. Iterating default weights: neutral primary
WARN  [DEBUG][util/divineRGBVal.html]  .--. Iterating default weights: primary primary
WARN  [DEBUG][util/divineRGBVal.html]  .+-. Found weight for K:primary. Set shade to:600
WARN  [DEBUG][util/divineRGBVal.html]  .--. Iterating default weights: secondary 600
WARN  [DEBUG][util/divineRGBVal.html]  -.-? avocado Scheme Color names unknown. Shortcut this by setting Site params.divineRGBVals.(primary,secondary,neutral) to the values discerned from divination.
WARN  [DEBUG][util/divineRGBVal.html]  ..-? Theme Datafile congo Accessible
WARN  [DEBUG][util/divineRGBVal.html]  -.-?  Iterating themeData: K:0 V:map[cherry:map[neutral:neutral primary:rose secondary:green]]
WARN  [DEBUG][util/divineRGBVal.html]  ..-? Evaluating Scheme 0 Name:cherry
WARN  [DEBUG][util/divineRGBVal.html]  -.-?  Iterating themeData: K:1 V:map[congo:map[neutral:gray primary:violet secondary:fuchsia]]
WARN  [DEBUG][util/divineRGBVal.html]  ..-? Evaluating Scheme 1 Name:congo
WARN  [DEBUG][util/divineRGBVal.html]  -.-?  Iterating themeData: K:2 V:map[fire:map[neutral:stone primary:orange secondary:rose]]
WARN  [DEBUG][util/divineRGBVal.html]  ..-? Evaluating Scheme 2 Name:fire
WARN  [DEBUG][util/divineRGBVal.html]  -.-?  Iterating themeData: K:3 V:map[ocean:map[neutral:slate primary:blue secondary:cyan]]
WARN  [DEBUG][util/divineRGBVal.html]  ..-? Evaluating Scheme 3 Name:ocean
WARN  [DEBUG][util/divineRGBVal.html]  -.-?  Iterating themeData: K:4 V:map[sapphire:map[neutral:slate primary:indigo secondary:pink]]
WARN  [DEBUG][util/divineRGBVal.html]  ..-? Evaluating Scheme 4 Name:sapphire
WARN  [DEBUG][util/divineRGBVal.html]  -.-?  Iterating themeData: K:5 V:map[avocado:map[neutral:stone primary:lime secondary:emerald]]
WARN  [DEBUG][util/divineRGBVal.html]  ..-? Evaluating Scheme 5 Name:avocado
WARN  [DEBUG][util/divineRGBVal.html]  ..*? Matched Scheme avocado! P: lime, S: emerald N: stone
WARN  [DEBUG][util/divineRGBVal.html]  +.+? Setting the value of scratch object $rgbItchy.neutral. Reading it Back to verify: stone
WARN  [DEBUG][util/divineRGBVal.html]  +.+? Setting the value of scratch object $rgbItchy.primary. Reading it Back to verify: lime
WARN  [DEBUG][util/divineRGBVal.html]  +.+? Setting the value of scratch object $rgbItchy.secondary. Reading it Back to verify: emerald
WARN  [DEBUG][util/divineRGBVal.html]  +.+? Color primary disambiguated to lime
WARN  [DEBUG][util/divineRGBVal.html]  +.+? Role secondary is emerald
WARN  [DEBUG][util/divineRGBVal.html]  +.+? Role neutral is stone
WARN  [DEBUG][util/divineRGBVal.html]  ...- Tailwind ColorMap Datafile twcolormap Accessible
WARN  [DEBUG][util/divineRGBVal.html]  *..- Evaluating Tailwind Mapdata 0:slate lime
WARN  [DEBUG][util/divineRGBVal.html]  *..- Evaluating Tailwind Mapdata 1:gray lime
WARN  [DEBUG][util/divineRGBVal.html]  *..- Evaluating Tailwind Mapdata 2:zinc lime
WARN  [DEBUG][util/divineRGBVal.html]  *..- Evaluating Tailwind Mapdata 3:neutral lime
WARN  [DEBUG][util/divineRGBVal.html]  *..- Evaluating Tailwind Mapdata 4:stone lime
WARN  [DEBUG][util/divineRGBVal.html]  *..- Evaluating Tailwind Mapdata 5:red lime
WARN  [DEBUG][util/divineRGBVal.html]  *..- Evaluating Tailwind Mapdata 6:orange lime
WARN  [DEBUG][util/divineRGBVal.html]  *..- Evaluating Tailwind Mapdata 7:amber lime
WARN  [DEBUG][util/divineRGBVal.html]  *..- Evaluating Tailwind Mapdata 8:yellow lime
WARN  [DEBUG][util/divineRGBVal.html]  *..- Evaluating Tailwind Mapdata 9:lime lime
WARN  [DEBUG][util/divineRGBVal.html]  **.+ Found color %!s(int=9) lime
WARN  [DEBUG][util/divineRGBVal.html]  **.- Evaluating 9:lime Shades :100 600
WARN  [DEBUG][util/divineRGBVal.html]  **.- Evaluating 9:lime Shades :200 600
WARN  [DEBUG][util/divineRGBVal.html]  **.- Evaluating 9:lime Shades :300 600
WARN  [DEBUG][util/divineRGBVal.html]  **.- Evaluating 9:lime Shades :400 600
WARN  [DEBUG][util/divineRGBVal.html]  **.- Evaluating 9:lime Shades :50 600
WARN  [DEBUG][util/divineRGBVal.html]  **.- Evaluating 9:lime Shades :500 600
WARN  [DEBUG][util/divineRGBVal.html]  **.- Evaluating 9:lime Shades :600 600
WARN  [DEBUG][util/divineRGBVal.html]  **.+ Found  lime:%!d(string=600) RGBVal: #65a30d
WARN  [DEBUG][util/divineRGBVal.html]  **** ReturnVal set #65a30d
WARN  [DEBUG][util/divineRGBVal.html]  **.- Evaluating 9:lime Shades :700 600
WARN  [DEBUG][util/divineRGBVal.html]  **.- Evaluating 9:lime Shades :800 600
WARN  [DEBUG][util/divineRGBVal.html]  **.- Evaluating 9:lime Shades :900 600
WARN  [partials/favicons.html]  - divineRGB: #65a30d

In its current state, it can be used as follows:

Divine the default RGB Value for a theme-abstracted tailwind color

{{- $rgbval := (partial "util/divineRGBVal.html" (dict "context" . "color" "primary"  )) -}}
{{- $rgbval }}

Would output: #65a30d

Divine the tailwind color name of a theme-abstracted color

{{- $twColor := (partial "util/divineRGBVal.html" (dict "context" . "color" "primary" "return" "TWColor"  )) -}}
{{- $twColor }}

Would output: lime

Divine the default tailwind-style color-shade Value for a theme-abstracted tailwind color

{{- $twC-S := (partial "util/divineRGBVal.html" (dict "context" . "color" "primary" "return" "TWColorShade"  )) -}}
{{- $twC-S }}

Would output: lime-600

Divine the RGB Value for a theme-abstracted color-weight combo

{{- $someOtherRGB := (partial "util/divineRGBVal.html" (dict "context" . "color" "primary" "shade" 500 )) -}}
{{- $someOtherRGB }}

Would output: #84cc16

Divine the RGB Value for a theme-abstracted color-weight combo of another colorscheme

{{- $someOtherColorSchemesColor := (partial "util/divineRGBVal.html" (dict "context" . "color" "primary" "shade" "500" "scheme" "cherry" )) -}}

{{- $someOtherColorSchemesColor }}

Would output: #f43f5e

Divine the tailwind-style color-shade for a theme-abstracted color-weight combo for another colorscheme

{{- $someOtherColorSchemesDefaultColor := (partial "util/divineRGBVal.html" (dict "context" . "color" "primary" "scheme" "cherry" "return" "TWColorShade" )) -}}
{{$someOtherColorSchemesDefaultColor }}

Would output: rose-600

with a little bit of iteration and a smattering of HTML/css:

Show me a list[^1] of all the colors of all congo colorschemes:

{{- $t  := slice "cherry" "congo" "fire" "ocean" "sapphire" "avocado" "slate"  -}}
{{- $tc := slice "primary" "secondary" "neutral" -}}
{{- $w  := slice 50 100 200 300 400 500 600 700 800 900 -}}
{{- range $tK, $scheme := $t -}}
    <hr/><h2 class="text-center font-extrabold">
      {{- $scheme }}</h2><hr/>
{{-   range $cK, $color := $tc -}}
      <table>
        <tr class="ring-1 bg-blue-600/10">
          <th class="ring-1 w-10% px-2 rounded-xl">{{- $color }}</th>
{{-   $tcolor := (partial "util/divineRGBVal.html" (dict "context" . "color" $color "scheme" $scheme "return" "TWColor" )) -}}
{{-	  range $sK, $shade := $w  -}}
{{-      $val := (partial "util/divineRGBVal.html" (dict "context" . "color" $color "shade" $shade "scheme" $scheme  )) -}}
          <td class="ring-1 rounded-xl"><div class="p-2 m-2 ring-2  rounded-xl text-black {{ printf "bg-%s-%d" $tcolor $shade }}">
            {{- $val }}</div><div class="p-1">
            {{- printf "%s-%d" $tcolor $shade -}}
          </div></td>
{{-	   end -}}
        </tr>
{{-	 end -}}
      </table>
    <hr/>
{{- end  -}}

divineRGBVal-All-Schemes-All-Colors

or:

Create an ugly table of all the tailwind colors

{{- $t  := slice "avocado" -}}
{{- $tc := slice  "slate" "gray" "zinc" "neutral" "stone" "red" "orange" "amber" "yellow" "lime" "green" "emerald" "teal" "cyan" "sky" "blue" "indigo" "violet" "purple" "fuchsia" "pink" "rose" -}}
{{- $w  := slice 50 100 200 300 400 500 600 700 800 900 -}}
{{- range $tK, $scheme := $t -}}
      <hr/><h2 class="text-center font-extrabold">Tailwind Colors</h2><hr/>
{{-   range $cK, $color := $tc -}}
        <table>
          <tr class="bg-blue-600/10"><th class="w-10% px-2 rounded-xl">{{- $color }}</th>
{{-	    range $sK, $shade := $w  -}}
{{-       $val := (partial "util/divineRGBVal.html" (dict "context" . "color" $color "shade" $shade "scheme" $scheme  )) -}}
            <td class="ring-1 rounded-xl"><div class="p-2 m-2 ring-2  rounded-xl text-black {{ printf "bg-%s-%d" $color $shade }}">
              {{- $val }}</div><div class="p-1">{{printf "%s-%d" $color $shade}}</div></td>
{{-	    end -}}
          </tr>
{{-	  end -}}
        </table><hr/>
{{- end  -}}

divineRGBVal-allTailwind

Thoughts?

[^1]: (Admittedly, somewhat terribly formatted, but you get the point.)

wolfspyre avatar Nov 23 '23 21:11 wolfspyre

Deploy Preview for hugo-congo ready!

Built without sensitive environment variables

Name Link
Latest commit 4a72ee4cc9174dc89a08fc4855b8d21804c2eb6d
Latest deploy log https://app.netlify.com/sites/hugo-congo/deploys/66291dfeb73b24000845c4e9
Deploy Preview https://deploy-preview-716--hugo-congo.netlify.app
Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

netlify[bot] avatar Nov 23 '23 21:11 netlify[bot]

I really like the idea behind this feature. One of the things that has really bugged me is that the RGB values are required to make the Tailwind theming work as I think it's a horrible hacky way of solving it. I had hoped they would implement a cleaner way in the upstream project but alas it doesn't seem to be happening.

There's lots of voodoo that I've done around the place to implement the colours into various features and so this is potentially one way to clean it all up. I've only had a very quick look at your implementation but some high level questions pop to mind:

  • Can we automate getting the colour mapping from tailwind directly? For instance, in npm when building the stylesheet could it also copy the latest colours into the data folder so they're always in sync?
  • I wonder if the config part is too rigid in terms of the shades it's using and if it should support passing a shade value?

There's probably a lot more but that's my initial thoughts.

jpanther avatar Nov 25 '23 07:11 jpanther

yeah.. there’s a few ways to make this less fucky™️

my intent with submitting this as-is was to come to the party with beer…

IE this works and serves as a starting point for a more elegant solution.

  • I’ll ask the tailwind kids if there’s a way to emit a truthy tailwind color map that’s programatically consumable, and report back.

  • re config question: i’m not sure i grok what you’re asking.

as I understand it:

tailwind supports T color names, each with the S shade values: 50, 100, 200, 300, 400, 500, 600, 700, 800, 900

congo provides C color schemes, each of which abstracts 3 tailwind T colors into ‘primary’ ‘secondary’ and ‘neutral’

if tailwind is configured to provide more S shades per T color, the tailwind color map would need to be expanded, to, say include

50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900, 950, 1000, 11

the only validation I’m doing wrt shade is that the requested shade ends with a 0. so as written, a shade with an ending value of 1-9 would be unparsable, but the liklihood of that scenario is pretty low unless we opt to start using quarter values in shades ie 25, 50, 75; which feels unlikely?

as far as “default values” go, the existing congo data file provides

  • a “default” S shade for primary secondary and neutral, (the values of which i pulled out of…… uh…. thin air)
  • a fallback value in case the user requested a T color and did not provide an S shade.

if you ask it to divine the rgb value of T: blue S: 100, it should work properly assuming the tailwind color map has a value for blue-100.

if you feed divineRGBVal C “primary” S “900” it should return the rgb vals of the T color associated with C primary at S shade 900

what am I missing?

wolfspyre avatar Nov 25 '23 17:11 wolfspyre

I reached out to tailwind here^1. Will followup as that conversation unfolds.

wolfspyre avatar Nov 25 '23 18:11 wolfspyre

I also think using the word "divine" here is odd... something like getRGBFromTailwind sounds clearer as to what the function is actually doing. That said, I haven't really come up with a naming standard for theme functions.

jpanther avatar Nov 25 '23 23:11 jpanther

definitely different, for sure... I was going with divination

https://en.wikipedia.org/wiki/Divination https://en.wikipedia.org/wiki/Greek_divination

To convey the voodoo/waving of hands/consumption of snake oil/ etc...

Because we're creating a secondary truthy source, and blindly trusting it....

I'm not ATTACHED to the name... I just didn't want it to convey a sense of "I AM TOTALLY ACCURATE AND YOU SHOULD BELIEVE ME WITHOUT QUESTION" as is ;)

wolfspyre avatar Nov 25 '23 23:11 wolfspyre

so whats next here?

wolfspyre avatar Apr 22 '24 17:04 wolfspyre

I've since refined the way I'm presenting the currently usable colors here

I could add this into the PR if ya want, but I figured that the point was to have a tool to determine a color value...

wolfspyre avatar Apr 30 '24 20:04 wolfspyre