Files
kjol/go/webui/cards.go

74 lines
3.1 KiB
Go

package webui
import "kjol/wasmruntime/vdom"
// Port of web/kit/Cards.tsx. The `ui-card`/`no-flex` marker classes are kept so
// any page CSS targeting them still applies; baseline styling is Tailwind.
const cardBase = "ui-card bg-surface shadow-sm rounded-default w-full"
const cardWithPadding = cardBase + " p-5 flex-1"
const cardNoFlex = cardBase + " no-flex p-5"
const cardNoPaddingNoFlex = cardBase + " no-padding no-flex"
const borderCard = "border border-line-strong rounded-default p-5 w-full"
// cutCornerCard uses two clip-path pseudo-elements to notch opposite corners.
const cutCornerCard = "relative isolate p-5 w-full " +
"before:content-[''] before:absolute before:inset-0 before:bg-surface-strong before:-z-20 " +
"before:[clip-path:polygon(16px_0,100%_0,100%_calc(100%_-_16px),calc(100%_-_16px)_100%,0_100%,0_16px)] " +
"after:content-[''] after:absolute after:inset-[1px] after:bg-white after:-z-10 " +
"after:[clip-path:polygon(15px_0,100%_0,100%_calc(100%_-_15px),calc(100%_-_15px)_100%,0_100%,0_15px)]"
func cardDiv(base, class string, children []*vdom.VNode) *vdom.VNode {
return vdom.Div(kids([]vdom.Mod{vdom.Attr("class", cx(base, class))}, children)...)
}
// Card is the standard padded, flex-grow card.
func Card(class string, children ...*vdom.VNode) *vdom.VNode {
return cardDiv(cardWithPadding, class, children)
}
// CardNoPadding is a card with no padding and no flex-grow.
func CardNoPadding(class string, children ...*vdom.VNode) *vdom.VNode {
return cardDiv(cardNoPaddingNoFlex, class, children)
}
// CardNoFlexGrow is a padded card that does not flex-grow.
func CardNoFlexGrow(class string, children ...*vdom.VNode) *vdom.VNode {
return cardDiv(cardNoFlex, class, children)
}
// BorderCard is a bordered (shadowless) card.
func BorderCard(class string, children ...*vdom.VNode) *vdom.VNode {
return cardDiv(borderCard, class, children)
}
// BorderCutCornerCard is a card with two notched corners (clip-path).
func BorderCutCornerCard(class string, children ...*vdom.VNode) *vdom.VNode {
return cardDiv(cutCornerCard, class, children)
}
const cardHeader = "text-xl tracking-tight text-ink mb-5"
const cardHeaderHR = "text-line mt-1 mb-3"
// CardHeader renders a card title followed by a divider.
func CardHeader(class string, children ...*vdom.VNode) *vdom.VNode {
mods := kids([]vdom.Mod{vdom.Attr("class", cx(cardHeader, class))}, children)
mods = append(mods, vdom.Hr(vdom.Attr("class", cardHeaderHR)))
return vdom.Div(mods...)
}
// CardHeaderTextCenter is CardHeader, centered.
func CardHeaderTextCenter(class string, children ...*vdom.VNode) *vdom.VNode {
mods := kids([]vdom.Mod{vdom.Attr("class", cx(cardHeader, "text-center", class))}, children)
mods = append(mods, vdom.Hr(vdom.Attr("class", cardHeaderHR)))
return vdom.Div(mods...)
}
// CardSubheader renders a smaller secondary heading.
func CardSubheader(class string, children ...*vdom.VNode) *vdom.VNode {
return vdom.Div(kids([]vdom.Mod{vdom.Attr("class", cx("text-lg tracking-tight text-ink mb-2", class))}, children)...)
}
// CardSpacer is vertical spacing between cards.
func CardSpacer() *vdom.VNode { return vdom.Div(vdom.Attr("class", "mb-6")) }