~repos /gromer

#golang#htmx#ssr

git clone https://pyrossh.dev/repos/gromer.git

gromer is a framework and cli to build multipage web apps in golang using htmx and alpinejs.



file:

gsx/twx.go



package gsx
import "strings"
type KeyValues struct {
Keys M
Values MS
}
var colors = KeyValues{
Keys: M{
"bg": "background-color",
"text": "color",
"divide": "border-color",
"border": "border-color",
"ring": "--tw-ring-color",
"border-l": "border-left-color",
"border-r": "border-right-color",
"border-t": "border-top-color",
"border-b": "border-bottom-color",
},
Values: MS{
"transparent": "transparent",
"current": "currentColor",
"black": "rgba(0, 0, 0, 1)",
"white": "rgba(255, 255, 255, 1)",
"gray-50": "rgba(249, 250, 251, 1)",
"gray-100": "rgba(243, 244, 246, 1)",
"gray-200": "rgba(229, 231, 235, 1)",
"gray-300": "rgba(209, 213, 219, 1)",
"gray-400": "rgba(156, 163, 175, 1)",
"gray-500": "rgba(107, 114, 128, 1)",
"gray-600": "rgba(75, 85, 99, 1)",
"gray-700": "rgba(55, 65, 81, 1)",
"gray-800": "rgba(31, 41, 55, 1)",
"gray-900": "rgba(17, 24, 39, 1)",
"red-50": "rgba(254, 242, 242, 1)",
"red-100": "rgba(254, 226, 226, 1)",
"red-200": "rgba(254, 202, 202, 1)",
"red-300": "rgba(252, 165, 165, 1)",
"red-400": "rgba(248, 113, 113, 1)",
"red-500": "rgba(239, 68, 68, 1)",
"red-600": "rgba(220, 38, 38, 1)",
"red-700": "rgba(185, 28, 28, 1)",
"red-800": "rgba(153, 27, 27, 1)",
"red-900": "rgba(127, 29, 29, 1)",
"yellow-50": "rgba(255, 251, 235, 1)",
"yellow-100": "rgba(254, 243, 199, 1)",
"yellow-200": "rgba(253, 230, 138, 1)",
"yellow-300": "rgba(252, 211, 77, 1)",
"yellow-400": "rgba(251, 191, 36, 1)",
"yellow-500": "rgba(245, 158, 11, 1)",
"yellow-600": "rgba(217, 119, 6, 1)",
"yellow-700": "rgba(180, 83, 9, 1)",
"yellow-800": "rgba(146, 64, 14, 1)",
"yellow-900": "rgba(120, 53, 15, 1)",
"green-50": "rgba(236, 253, 245, 1)",
"green-100": "rgba(209, 250, 229, 1)",
"green-200": "rgba(167, 243, 208, 1)",
"green-300": "rgba(110, 231, 183, 1)",
"green-400": "rgba(52, 211, 153, 1)",
"green-500": "rgba(16, 185, 129, 1)",
"green-600": "rgba(5, 150, 105, 1)",
"green-700": "rgba(4, 120, 87, 1)",
"green-800": "rgba(6, 95, 70, 1)",
"green-900": "rgba(6, 78, 59, 1)",
"blue-50": "rgba(239, 246, 255, 1)",
"blue-100": "rgba(219, 234, 254, 1)",
"blue-200": "rgba(191, 219, 254, 1)",
"blue-300": "rgba(147, 197, 253, 1)",
"blue-400": "rgba(96, 165, 250, 1)",
"blue-500": "rgba(59, 130, 246, 1)",
"blue-600": "rgba(37, 99, 235, 1)",
"blue-700": "rgba(29, 78, 216, 1)",
"blue-800": "rgba(30, 64, 175, 1)",
"blue-900": "rgba(30, 58, 138, 1)",
"indigo-50": "rgba(238, 242, 255, 1)",
"indigo-100": "rgba(224, 231, 255, 1)",
"indigo-200": "rgba(199, 210, 254, 1)",
"indigo-300": "rgba(165, 180, 252, 1)",
"indigo-400": "rgba(129, 140, 248, 1)",
"indigo-500": "rgba(99, 102, 241, 1)",
"indigo-600": "rgba(79, 70, 229, 1)",
"indigo-700": "rgba(67, 56, 202, 1)",
"indigo-800": "rgba(55, 48, 163, 1)",
"indigo-900": "rgba(49, 46, 129, 1)",
"purple-50": "rgba(245, 243, 255, 1)",
"purple-100": "rgba(237, 233, 254, 1)",
"purple-200": "rgba(221, 214, 254, 1)",
"purple-300": "rgba(196, 181, 253, 1)",
"purple-400": "rgba(167, 139, 250, 1)",
"purple-500": "rgba(139, 92, 246, 1)",
"purple-600": "rgba(124, 58, 237, 1)",
"purple-700": "rgba(109, 40, 217, 1)",
"purple-800": "rgba(91, 33, 182, 1)",
"purple-900": "rgba(76, 29, 149, 1)",
"pink-50": "rgba(253, 242, 248, 1)",
"pink-100": "rgba(252, 231, 243, 1)",
"pink-200": "rgba(251, 207, 232, 1)",
"pink-300": "rgba(249, 168, 212, 1)",
"pink-400": "rgba(244, 114, 182, 1)",
"pink-500": "rgba(236, 72, 153, 1)",
"pink-600": "rgba(219, 39, 119, 1)",
"pink-700": "rgba(190, 24, 93, 1)",
"pink-800": "rgba(157, 23, 77, 1)",
"pink-900": "rgba(131, 24, 67, 1)",
},
}
var spacing = KeyValues{
Keys: M{
"mr": "margin-right",
"ml": "margin-left",
"mt": "margin-top",
"mb": "margin-bottom",
"mx": Arr{
"margin-left",
"margin-right",
},
"my": Arr{
"margin-top",
"margin-bottom",
},
"m": "margin",
"pr": "padding-right",
"pl": "padding-left",
"pt": "padding-top",
"pb": "padding-bottom",
"px": Arr{
"padding-left",
"padding-right",
},
"py": Arr{
"padding-top",
"padding-bottom",
},
"p": "padding",
},
Values: MS{
"0": "0px",
"1": "0.25rem",
"2": "0.5rem",
"3": "0.75rem",
"4": "1rem",
"5": "1.25rem",
"6": "1.5rem",
"7": "1.75rem",
"8": "2rem",
"9": "2.25rem",
"10": "2.5rem",
"11": "2.75rem",
"12": "3rem",
"14": "3.5rem",
"16": "4rem",
"20": "5rem",
"24": "6rem",
"28": "7rem",
"32": "8rem",
"36": "9rem",
"40": "10rem",
"44": "11rem",
"48": "12rem",
"52": "13rem",
"56": "14rem",
"60": "15rem",
"64": "16rem",
"72": "18rem",
"80": "20rem",
"96": "24rem",
"auto": "auto",
"px": "1px",
"0.5": "0.125rem",
"1.5": "0.375rem",
"2.5": "0.625rem",
"3.5": "0.875rem",
},
}
var radius = KeyValues{
Keys: M{
"rounded": "border-radius",
"rounded-t": "border-top-radius",
"rounded-r": "border-right-radius",
"rounded-l": "border-left-radius",
"rounded-b": "border-bottom-radius",
"rounded-tl": Arr{
"border-top-radius",
"border-left-radius",
},
"rounded-tr": Arr{
"border-top-radius",
"border-right-radius",
},
"rounded-bl": Arr{
"border-bottom-radius",
"border-left-radius",
},
"rounded-br": Arr{
"border-bottom-radius",
"border-right-radius",
},
},
Values: MS{
"none": "0px",
"sm": "0.125rem",
"": "0.25rem",
"md": "0.375rem",
"lg": "0.5rem",
"xl": "0.75rem",
"2xl": "1rem",
"3xl": "1.5rem",
"full": "9999px",
},
}
var borders = KeyValues{
Keys: M{
"border": "border-width",
"border-l": "border-left-width",
"border-r": "border-right-width",
"border-t": "border-top-width",
"border-b": "border-bottom-width",
},
Values: MS{
"0": "0px",
"2": "2px",
"4": "4px",
"8": "8px",
"": "1px",
},
}
var sizes = KeyValues{
Keys: M{
"h": "height",
"w": "width",
"top": "top",
"left": "left",
"bottom": "bottom",
"right": "right",
"min-h": "min-height",
"min-w": "min-width",
"max-h": "max-height",
"max-w": "max-width",
},
Values: MS{
"auto": "auto",
"min": "min-content",
"max": "max-content",
"fit": "fit-content",
"0": "0px",
"0.5": "0.125rem",
"1": "0.25rem",
"1.5": "0.375rem",
"2": "0.5rem",
"2.5": "0.625rem",
"3": "0.75rem",
"3.5": "0.875rem",
"4": "1rem",
"5": "1.25rem",
"6": "1.5rem",
"7": "1.75rem",
"8": "2rem",
"9": "2.25rem",
"10": "2.5rem",
"11": "2.75rem",
"12": "3rem",
"14": "3.5rem",
"16": "4rem",
"20": "5rem",
"24": "6rem",
"28": "7rem",
"32": "8rem",
"36": "9rem",
"40": "10rem",
"44": "11rem",
"48": "12rem",
"52": "13rem",
"56": "14rem",
"60": "15rem",
"64": "16rem",
"72": "18rem",
"80": "20rem",
"96": "24rem",
"px": "1px",
"1/2": "50%",
"1/3": "33.33%",
"2/3": "66.66%",
"1/4": "25%",
"2/4": "50%",
"3/4": "75%",
"1/5": "20%",
"2/5": "40%",
"3/5": "60%",
"4/5": "80%",
"1/6": "16.66%",
"2/6": "33.33%",
"3/6": "50%",
"4/6": "66.66%",
"5/6": "83.33%",
"1/12": "8.33%",
"2/12": "16.66%",
"3/12": "25%",
"4/12": "33.33%",
"5/12": "41.66%",
"6/12": "50%",
"7/12": "58.33%",
"8/12": "66.66%",
"9/12": "75%",
"10/12": "83.33%",
"11/12": "91.66%",
"full": "100%",
"none": "none",
"xs": "20rem",
"sm": "24rem",
"md": "28rem",
"lg": "32rem",
"xl": "36rem",
"2xl": "42rem",
"3xl": "48rem",
"4xl": "56rem",
"5xl": "64rem",
"6xl": "72rem",
"7xl": "80rem",
"prose": "65ch",
"screen-sm": "640px",
"screen-md": "768px",
"screen-lg": "1024px",
"screen-xl": "1280px",
"screen-2xl": "1536px",
},
}
var twClassLookup = MS{
"flex": "display: flex;",
"inline-flex": "display: inline-flex;",
"block": "display: block;",
"inline-block": "display: inline-block;",
"inline": "display: inline;",
"table": "display: table;",
"inline-table": "display: inline-table;",
"grid": "display: grid;",
"inline-grid": "display: inline-grid;",
"contents": "display: contents;",
"list-item": "display: list-item;",
"hidden": "display: none;",
"flex-1": "flex: 1;",
"flex-row": "flex-direction: row;",
"flex-col": "flex-direction: column;",
"flex-wrap": "flex-wrap: wrap;",
"flex-nowrap": "flex-wrap: nowrap;",
"flex-wrap-reverse": "flex-wrap: wrap-reverse;",
"items-baseline": "align-items: baseline;",
"items-start": "align-items: flex-start;",
"items-center": "align-items: center;",
"items-end": "align-items: flex-end;",
"items-stretch": "align-items: stretch;",
"justify-start": "justify-content: flex-start;",
"justify-end": "justify-content: flex-end;",
"justify-center": "justify-content: center;",
"justify-between": "justify-content: space-between;",
"justify-around": "justify-content: space-around;",
"justify-evenly": "justify-content: space-evenly;",
"uppercase": "text-transform: uppercase",
"lowercase": "text-transform: lowercase",
"capitalize": "text-transform: capitalize",
"normal-case": "text-transform: normal-case",
"text-left": "text-align: left;",
"text-center": "text-align: center;",
"text-right": "text-align: right;",
"text-justify": "text-align: justify;",
"underline": "text-decoration: underline;",
"line-through": "text-decoration: line-through;",
"no-underline": "text-decoration: none;",
"whitespace-normal": "white-space: normal;",
"whitespace-nowrap": "white-space: nowrap;",
"whitespace-pre": "white-space: pre;",
"whitespace-pre-line": "white-space: pre-line;",
"whitespace-pre-wrap": "white-space: pre-wrap;",
"break-normal": "word-break: normal; overflow-wrap: normal;",
"break-words": "word-break: break-word;",
"break-all": "word-break: break-all;",
"font-sans": "font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";",
"font-serif": "font-family: ui-serif, Georgia, Cambria, \"Times New Roman\", Times, serif;",
"font-mono": "font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;",
"font-thin": "font-weight: 100;",
"font-extralight": "font-weight: 200;",
"font-light": "font-weight: 300;",
"font-normal": "font-weight: 400;",
"font-medium": "font-weight: 500;",
"font-semibold": "font-weight: 600;",
"font-bold": "font-weight: 700;",
"font-extrabold": "font-weight: 800;",
"font-black": "font-weight: 900;",
"text-xs": "font-size: 0.75rem; line-height: 1rem;",
"text-sm": "font-size: 0.875rem; line-height: 1.25rem;",
"text-base": "font-size: 1rem; line-height: 1.5rem;",
"text-lg": "font-size: 1.125rem; line-height: 1.75rem;",
"text-xl": "font-size: 1.25rem; line-height: 1.75rem;",
"text-2xl": "font-size: 1.5rem; line-height: 2rem;",
"text-3xl": "font-size: 1.875rem; line-height: 2.25rem;",
"text-4xl": "font-size: 2.25rem; line-height: 2.5rem;",
"text-5xl": "font-size: 3rem; line-height: 1;",
"text-6xl": "font-size: 3.75rem;; line-height: 1;",
"text-7xl": "font-size: 4.5rem; line-height: 1;",
"text-8xl": "font-size: 6rem; line-height: 1;",
"text-9xl": "font-size: 8rem; line-height: 1;",
"cursor-auto": "cursor: auto;",
"cursor-default": "cursor: default;",
"cursor-pointer": "cursor: pointer;",
"cursor-wait": "cursor: wait;",
"cursor-text": "cursor: text;",
"cursor-move": "cursor: move;",
"cursor-help": "cursor: help;",
"cursor-not-allowed": "cursor: not-allowed;",
"pointer-events-none": "pointer-events: none;",
"pointer-events-auto": "pointer-events: auto;",
"select-none": "user-select: none;",
"select-text": "user-select: text;",
"select-all": "user-select: all;",
"select-auto": "user-select: auto;",
"w-screen": "width: 100vw;",
"h-screen": "height: 100vh;",
"static": "position: static;",
"fixed": "position: fixed;",
"absolute": "position: absolute;",
"relative": "position: relative;",
"sticky": "position: sticky;",
"overflow-auto": "overflow: auto;",
"overflow-hidden": "overflow: hidden;",
"overflow-visible": "overflow: visible;",
"overflow-scroll": "overflow: scroll;",
"overflow-x-auto": "overflow-x: auto;",
"overflow-y-auto": "overflow-y: auto;",
"overflow-x-hidden": "overflow-x: hidden;",
"overflow-y-hidden": "overflow-y: hidden;",
"overflow-x-visible": "overflow-x: visible;",
"overflow-y-visible": "overflow-y: visible;",
"overflow-x-scroll": "overflow-x: scroll;",
"overflow-y-scroll": "overflow-y: scroll;",
"origin-center": "transform-origin: center;",
"origin-top": "transform-origin: top;",
"origin-top-right": "transform-origin: top right;",
"origin-right": "transform-origin: right;",
"origin-bottom-right": "transform-origin: bottom right;",
"origin-bottom": "transform-origin: bottom;",
"origin-bottom-left": "transform-origin: bottom left;",
"origin-left": "transform-origin: left;",
"origin-top-left": "transform-origin: top left;",
"shadow-sm": "box-shadow: 0 0 #0000, 0 0 #0000, 0 1px 2px 0 rgba(0, 0, 0, 0.05);",
"shadow": "box-shadow: 0 0 #0000, 0 0 #0000, 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);",
"shadow-md": "box-shadow: 0 0 #0000, 0 0 #0000, 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);",
"shadow-lg": "box-shadow: 0 0 #0000, 0 0 #0000, 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);",
"shadow-xl": "box-shadow: 0 0 #0000, 0 0 #0000, 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);",
"shadow-2xl": "box-shadow: 0 0 #0000, 0 0 #0000, 0 25px 50px -12px rgba(0, 0, 0, 0.25);",
"shadow-inner": "box-shadow: 0 0 #0000, 0 0 #0000, inset 0 2px 4px 0 rgba(0, 0, 0, 0.06);",
"shadow-none": "box-shadow: 0 0 #0000, 0 0 #0000, 0 0 #0000;",
"ring-inset": "--tw-ring-inset: insest;",
"ring-0": "box-shadow: 0 0 0 calc(0px + 0px) rgba(59, 130, 246, 0.5);",
"ring-1": "box-shadow: 0 0 0 calc(1px + 0px) rgba(59, 130, 246, 0.5);",
"ring-2": "box-shadow: 0 0 0 calc(2px + 0px) rgba(59, 130, 246, 0.5);",
"ring-4": "box-shadow: 0 0 0 calc(4px + 0px) rgba(59, 130, 246, 0.5);",
"ring-8": "box-shadow: 0 0 0 calc(8px + 0px) rgba(59, 130, 246, 0.5);",
"ring": "box-shadow: 0 0 0 calc(3px + 0px) rgba(59, 130, 246, 0.5);",
"invisible": "visibility: hidden;",
"opacity-0": "opacity: 0;",
"opacity-5": "opacity: 0.05;",
"opacity-10": "opacity: 0.1;",
"opacity-20": "opacity: 0.2;",
"opacity-25": "opacity: 0.25;",
"opacity-30": "opacity: 0.3;",
"opacity-40": "opacity: 0.4;",
"opacity-50": "opacity: 0.5;",
"opacity-60": "opacity: 0.6;",
"opacity-70": "opacity: 0.7;",
"opacity-75": "opacity: 0.75;",
"opacity-80": "opacity: 0.8;",
"opacity-90": "opacity: 0.9;",
"opacity-95": "opacity: 0.95;",
"opacity-100": "opacity: 1;",
"list-none": "list-style-type: none;",
"list-disc": "list-style-type: disc;",
"list-decimal": "list-style-type: decimal;",
"min-h-screen": "height: 100vh;",
"min-w-screen": "width: 100vw;",
}
func init() {
mapApply(sizes)
mapApply(spacing)
mapApply(colors)
mapApply(borders)
mapApply(radius)
}
func mapApply(obj KeyValues) {
for key, v := range obj.Keys {
for vkey, vv := range obj.Values {
suffix := ""
if vkey != "" {
suffix = "-" + vkey
}
className := key + suffix
if vstring, ok := v.(string); ok {
twClassLookup[className] = vstring + ": " + vv + ";"
}
if varr, ok := v.(Arr); ok {
twClassLookup[className] = ""
for _, kk := range varr {
twClassLookup[className] += kk.(string) + ": " + vv + ";"
}
}
}
}
}
func GetColor(k string) string {
return colors.Values[k]
}
func getClassName(parent, k string) string {
if parent != "" {
if k == "container" {
return "." + parent
} else {
return "." + parent + " ." + k
}
}
return "." + k
}
func computeCss(classMap M, parent string) string {
p := "\n"
for k, v := range classMap {
switch it := v.(type) {
case string:
className := getClassName(parent, k)
p += className + " {\n"
classes := strings.Split(it, " ")
for _, c := range classes {
if s, ok := twClassLookup[c]; ok {
p += " " + s + "\n"
}
}
p += "}\n"
for _, c := range classes {
if strings.Contains(c, ":") {
arr := strings.Split(c, ":")
prefix := arr[0]
class := arr[1]
if prefix == "placeholder" {
p += "\n" + className + "::placeholder" + " {\n"
if s, ok := twClassLookup[class]; ok {
p += " " + s + "\n"
}
p += "}\n"
} else if prefix == "hover" {
p += "\n" + className + ":hover" + " {\n"
if s, ok := twClassLookup[class]; ok {
p += " " + s + "\n"
}
p += "}\n"
}
}
}
case M:
p += computeCss(it, k)
}
}
return p
}