74 lines
3.1 KiB
Go
74 lines
3.1 KiB
Go
package webui
|
|
|
|
import "kjol/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-white 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-neutral-300 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-neutral-300 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.El("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-black mb-5"
|
|
const cardHeaderHR = "text-neutral-200 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.El("hr", vdom.Attr("class", cardHeaderHR)))
|
|
return vdom.El("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.El("hr", vdom.Attr("class", cardHeaderHR)))
|
|
return vdom.El("div", mods...)
|
|
}
|
|
|
|
// CardSubheader renders a smaller secondary heading.
|
|
func CardSubheader(class string, children ...*vdom.VNode) *vdom.VNode {
|
|
return vdom.El("div", kids([]vdom.Mod{vdom.Attr("class", cx("text-lg tracking-tight text-black mb-2", class))}, children)...)
|
|
}
|
|
|
|
// CardSpacer is vertical spacing between cards.
|
|
func CardSpacer() *vdom.VNode { return vdom.El("div", vdom.Attr("class", "mb-6")) }
|