[ @sdxc/u/state ]
has
Sugar over when("&:has({selector})", input).
import { has } from "@sdxc/u/state";Quick reference
Every documented call, beside the CSS it emits.
| Call | CSS |
|---|---|
u.has("input:user-invalid", u.border("danger")) | css({ "&:has(input:user-invalid)": { borderColor: "..." } }) |
u.has("img", u.p(4)) | css({ "&:has(img)": { padding: "..." } }) |
Examples
Basic example
Pass a selector to has() to style an element by what it contains, like a card holding a checked radio. Pick a plan:
<div mix={[...]}>
<label
mix={[
hstack({ gap: 2, align: "center" }),
p(3, 4),
rounded("lg"),
border({ color: "neutral.border", width: 2 }),
has("input:checked", [border("brand"), bg("brand.tint")]),
cursor("pointer"),
]}
>
<input type="radio" name="has-plan" checked mix={[accent()]} />
<span mix={[text("sm"), weight("semibold")]}>Starter</span>
</label>
<label
mix={[
hstack({ gap: 2, align: "center" }),
p(3, 4),
rounded("lg"),
border({ color: "neutral.border", width: 2 }),
has("input:checked", [border("brand"), bg("brand.tint")]),
cursor("pointer"),
]}
>
<input type="radio" name="has-plan" mix={[accent()]} />
<span mix={[text("sm"), weight("semibold")]}>Team</span>
</label>
</div>Styling by a child's state
Any selector works, like input:user-invalid to color a label from its field. Type a word that is not a URL, then click outside:
<label
mix={[
vstack({ gap: 1 }),
text("sm"),
weight("medium"),
fg(),
has("input:user-invalid", fg("danger")),
]}
>
Website
<input type="url" placeholder="https://" mix={[border("neutral.border"), ...]} />
</label>Responsive design
Wrap the call in a container query to scope it to one width.
u.at("md", u.has("input:user-invalid", u.border("danger")))Signature
u.has(selector: string, input: UtilityInput<Node>)