Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion apps/website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
"@types/react": "catalog:",
"@types/react-dom": "catalog:",
"@vitejs/plugin-react": "catalog:",
"bearbones": "workspace:*",
"react": "catalog:",
"react-dom": "catalog:"
},
Expand Down
5 changes: 4 additions & 1 deletion apps/website/panda.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import { bearbonesHooks } from "@bearbones/vite";
export default defineConfig({
preflight: true,
include: ["./src/**/*.{ts,tsx}"],
exclude: [],
// Type-only tests author dummy `css()` calls solely to exercise the
// augmented `css()` typing surface — they're never executed and shouldn't
// contribute classes to the production stylesheet. Skip them at extraction.
exclude: ["./src/__type-tests__/**/*"],
outdir: "styled-system",
jsxFramework: "react",
// We don't list presets explicitly because Panda's defaults
Expand Down
51 changes: 34 additions & 17 deletions apps/website/src/Demo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@
// The bearbones `codegen:prepare` hook patches Panda's emitted `css.d.ts` so
// `css()` accepts utility strings + marker condition keys natively — no cast
// needed at the call site.
import { css } from "../styled-system/css";
import { cx } from "bearbones";
import { cardMarker, rowMarker } from "./markers.ts";
import { css, cx } from "../styled-system/css";
import { cardMarker, innerMarker, rowMarker } from "./markers.ts";

export function Demo() {
return (
Expand Down Expand Up @@ -78,22 +77,40 @@ export function Demo() {
condition keys at build time; prescan registers the (modifier,
relation) pairs so Panda's extractor emits matching CSS.
*/}
<article className={cx(css("p-4", "rounded-md", "bg-gray-100"), cardMarker.anchor)}>
<p
className={css("text-sm", {
<article
className={cx(
cardMarker.anchor,
css("p-4", "rounded-md", "bg-gray-100", {
// Underscore form: explicit `.is.<relation>` against a known state.
[cardMarker._focusVisible.is.descendant]: "text-blue-500",
})}
>
Tab here — when this paragraph receives :focus-visible (descendant relation), the
card-marker ancestor's text turns blue.
</p>
[innerMarker._focusVisible.is.descendant]: "bg-blue-500",
}),
)}
>
<label className={cx("flag-error", css("text-sm"))}>
When this input receives :focus-visible, the cards background turns blue and the next
paragraph text turns white.
<input
type="text"
className={cx(
innerMarker.anchor,
css("border-black", {
borderWidth: 1,
_focusVisible: {
outlineWidth: "1px",
outlineColor: "blue.500",
},
}),
)}
/>
</label>
<p
className={css("text-sm", {
// Call form: arbitrary CSS-fragment modifier.
[cardMarker(":has(.flag-error)").is.ancestor]: "text-red-500",
})}
tabIndex={0}
className={cx(
css("text-sm", {
// Call form: arbitrary CSS-fragment modifier.
[cardMarker("&:has(*:focus-visible)").is.ancestor]: "text-white",
[cardMarker("&:has(.flag-error)").is.ancestor]: "text-red-500",
}),
)}
>
Adding `.flag-error` anywhere inside the card flips this line red via `:has(...)`.
</p>
Expand Down
34 changes: 28 additions & 6 deletions apps/website/src/__type-tests__/css-typing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,37 @@ css({ "&:focus-within": "p-4" });
// Array of utility strings under an arbitrary nested selector.
css({ "&:focus-within": ["p-4", "bg-blue-500"] });

// Marker call form: arbitrary CSS-fragment modifier with explicit relation.
css({ [cardMarker(":has(.flag-error)").is.ancestor]: "text-red-500" });

// Marker underscore form: typed shortcut against a known pseudo-state with
// explicit relation.
// Marker call form: arbitrary Panda condition value with explicit relation.
// `&` is mandatory and is substituted with the marker's anchor selector.
css({ [cardMarker("&:has(.flag-error)").is.ancestor]: "text-red-500" });

// Marker underscore form: typed shortcut against a registered Panda
// condition with explicit relation. The condition value comes from
// `panda.config.conditions` (with preset-base defaults plus user
// extensions) and is substituted into the relation at lower-time.
css({ [cardMarker._focusVisible.is.descendant]: "text-blue-500" });

// Sibling relation works too.
css({ [cardMarker(":focus-within").is.sibling]: "text-gray-700" });
css({ [cardMarker("&:focus-within").is.sibling]: "text-gray-700" });

// Parent-nesting condition value — marker is descendant of state-bearing element.
css({ [cardMarker("[data-state=open] &").is.descendant]: "text-blue-500" });

// Mixing marker computed-keys with literal CSS properties in one object
// works: relation types are concrete literal templates parameterized on
// Id + Cond (no `${string}` widening), so TS preserves them as named
// property keys instead of collapsing to a string index signature.
css({
[cardMarker("& > *").is.descendant]: "text-red-500",
borderWidth: 1,
});

// Underscore form mixed with sibling property — same property keeps literal
// inference; TypeScript treats the marker chain key like any other property.
css({
[cardMarker._hover.is.ancestor]: "text-blue-500",
padding: "4",
});

// --- Rejected forms -----------------------------------------------------

Expand Down
2 changes: 1 addition & 1 deletion apps/website/src/markers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { marker } from "bearbones";
import { marker } from "../styled-system/css";

// Module-level marker declarations. The `@bearbones/vite` parser:before hook
// rewrites each `marker(...)` call to a synthesized object literal at build
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"scripts": {
"ready": "vp check && vp run -r test && vp run -r build",
"dev": "vp run website#dev",
"check": "vp run --filter '@bearbones/*' --filter bearbones build && vp run --filter website codegen && vp check && vp run -r test",
"check": "vp run --filter '@bearbones/*' build && vp run --filter website codegen && vp check && vp run -r test",
"fix": "vp fmt",
"prepare": "vp config"
},
Expand Down
Loading
Loading