Skip to content
GitHub

Screen

Custom filters for different screen displays

import Screen from "@/components/ui/pxl/screen";
import { SpriteCanvas } from "@/components/ui/pxl/sprite-canvas";
import { WidgetArea } from "@/components/ui/pxl/widget-area";
export default function ScreenPreview() {
return (
<WidgetArea size="sm">
<Screen
className="size-full flex items-center justify-center"
variant="lcd"
>
<Screen.Filter>
<SpriteCanvas
src="https://raw.githubusercontent.com/pxl-ui/registry/main/app/public/sprites/tiny_chick.png"
animation="Idle"
size="lg"
atlas={{
frames: {
"0": { frame: { x: 0, y: 0, w: 16, h: 16 } },
"1": { frame: { x: 16, y: 0, w: 16, h: 16 } },
"2": { frame: { x: 32, y: 0, w: 16, h: 16 } },
"3": { frame: { x: 48, y: 0, w: 16, h: 16 } },
},
meta: { frameTags: [{ name: "Idle", from: 0, to: 3 }] },
}}
/>
</Screen.Filter>
</Screen>
</WidgetArea>
);
}
pnpm dlx shadcn@latest add pxl-ui/registry/screen
import {
ScreenFilter,
ScreenProvider
} from "@/components/ui/pxl/screen";
<ScreenProvider variant="lcd">
<ScreenFilter>
</ScreenFilter>
</ScreenProvider>

Use the following composition to build a Screen:

ScreenProvider
└── ScreenFilter
import Screen from "@/components/ui/pxl/screen";
import { SpriteCanvas } from "@/components/ui/pxl/sprite-canvas";
import { WidgetArea } from "@/components/ui/pxl/widget-area";
export default function ScreenCRTExample() {
return (
<WidgetArea size="sm">
<Screen
className="size-full" variant="crt">
<Screen.Filter className="size-full flex items-center justify-center">
<SpriteCanvas
src="https://raw.githubusercontent.com/pxl-ui/registry/main/app/public/sprites/tiny_chick.png"
animation="Idle"
size="lg"
atlas={{
frames: {
"0": { frame: { x: 0, y: 0, w: 16, h: 16 } },
"1": { frame: { x: 16, y: 0, w: 16, h: 16 } },
"2": { frame: { x: 32, y: 0, w: 16, h: 16 } },
"3": { frame: { x: 48, y: 0, w: 16, h: 16 } },
},
meta: { frameTags: [{ name: "Idle", from: 0, to: 3 }] },
}}
/>
</Screen.Filter>
</Screen>
</WidgetArea>
);
}
import { type ComponentProps, useState } from "react";
import { Button } from "@/components/ui/pxl/button";
import Screen from "@/components/ui/pxl/screen";
import { SpriteCanvas } from "@/components/ui/pxl/sprite-canvas";
import { WidgetArea } from "@/components/ui/pxl/widget-area";
export default function ScreenLCDExample() {
const [background, setBackground] =
useState<ComponentProps<typeof Screen>["background"]>("none");
return (
<div className="w-full flex flex-col gap-2 items-center justify-center">
<Button
onClick={() =>
setBackground((prev) => (prev === "none" ? "filter" : "none"))
}
>
Toggle Background
</Button>
<WidgetArea size="sm">
<Screen
className="size-full flex items-center justify-center"
variant="lcd"
background={background}
>
<Screen.Filter>
<SpriteCanvas
src="https://raw.githubusercontent.com/pxl-ui/registry/main/app/public/sprites/tiny_chick.png"
animation="Idle"
size="lg"
atlas={{
frames: {
"0": { frame: { x: 0, y: 0, w: 16, h: 16 } },
"1": { frame: { x: 16, y: 0, w: 16, h: 16 } },
"2": { frame: { x: 32, y: 0, w: 16, h: 16 } },
"3": { frame: { x: 48, y: 0, w: 16, h: 16 } },
},
meta: { frameTags: [{ name: "Idle", from: 0, to: 3 }] },
}}
/>
</Screen.Filter>
</Screen>
</WidgetArea>
</div>
);
}
import { type ComponentProps, useState } from "react";
import { Button } from "@/components/ui/pxl/button";
import Screen from "@/components/ui/pxl/screen";
import { SpriteCanvas } from "@/components/ui/pxl/sprite-canvas";
import { WidgetArea } from "@/components/ui/pxl/widget-area";
export default function ScreenDarkExample() {
const [background, setBackground] =
useState<ComponentProps<typeof Screen>["background"]>("none");
return (
<div className="w-full flex flex-col gap-2 items-center justify-center">
<Button
onClick={() =>
setBackground((prev) => (prev === "none" ? "filter" : "none"))
}
>
Toggle Background
</Button>
<WidgetArea size="sm">
<Screen
className="size-full flex items-center justify-center"
variant="dark"
background={background}
>
<Screen.Filter>
<SpriteCanvas
src="https://raw.githubusercontent.com/pxl-ui/registry/main/app/public/sprites/tiny_chick.png"
animation="Idle"
size="lg"
atlas={{
frames: {
"0": { frame: { x: 0, y: 0, w: 16, h: 16 } },
"1": { frame: { x: 16, y: 0, w: 16, h: 16 } },
"2": { frame: { x: 32, y: 0, w: 16, h: 16 } },
"3": { frame: { x: 48, y: 0, w: 16, h: 16 } },
},
meta: { frameTags: [{ name: "Idle", from: 0, to: 3 }] },
}}
/>
</Screen.Filter>
</Screen>
</WidgetArea>
</div>
);
}
import { type ComponentProps, useState } from "react";
import { Button } from "@/components/ui/pxl/button";
import Screen from "@/components/ui/pxl/screen";
import { SpriteCanvas } from "@/components/ui/pxl/sprite-canvas";
import { WidgetArea } from "@/components/ui/pxl/widget-area";
export default function ScreenGreenExample() {
const [background, setBackground] =
useState<ComponentProps<typeof Screen>["background"]>("none");
return (
<div className="w-full flex flex-col gap-2 items-center justify-center">
<Button
onClick={() =>
setBackground((prev) => (prev === "none" ? "filter" : "none"))
}
>
Toggle Background
</Button>
<WidgetArea size="sm">
<Screen
className="size-full flex items-center justify-center"
variant="green"
background={background}
>
<Screen.Filter>
<SpriteCanvas
src="https://raw.githubusercontent.com/pxl-ui/registry/main/app/public/sprites/tiny_chick.png"
animation="Idle"
size="lg"
atlas={{
frames: {
"0": { frame: { x: 0, y: 0, w: 16, h: 16 } },
"1": { frame: { x: 16, y: 0, w: 16, h: 16 } },
"2": { frame: { x: 32, y: 0, w: 16, h: 16 } },
"3": { frame: { x: 48, y: 0, w: 16, h: 16 } },
},
meta: { frameTags: [{ name: "Idle", from: 0, to: 3 }] },
}}
/>
</Screen.Filter>
</Screen>
</WidgetArea>
</div>
);
}
import { type ComponentProps, useState } from "react";
import { Button } from "@/components/ui/pxl/button";
import Screen from "@/components/ui/pxl/screen";
import { SpriteCanvas } from "@/components/ui/pxl/sprite-canvas";
import { WidgetArea } from "@/components/ui/pxl/widget-area";
export default function ScreenGreenLightExample() {
const [background, setBackground] =
useState<ComponentProps<typeof Screen>["background"]>("none");
return (
<div className="w-full flex flex-col gap-2 items-center justify-center">
<Button
onClick={() =>
setBackground((prev) => (prev === "none" ? "filter" : "none"))
}
>
Toggle Background
</Button>
<WidgetArea size="sm">
<Screen
className="relative size-full flex items-center justify-center"
variant="greenLight"
background={background}
>
<Screen.Filter>
<SpriteCanvas
src="https://raw.githubusercontent.com/pxl-ui/registry/main/app/public/sprites/tiny_chick.png"
animation="Idle"
size="lg"
atlas={{
frames: {
"0": { frame: { x: 0, y: 0, w: 16, h: 16 } },
"1": { frame: { x: 16, y: 0, w: 16, h: 16 } },
"2": { frame: { x: 32, y: 0, w: 16, h: 16 } },
"3": { frame: { x: 48, y: 0, w: 16, h: 16 } },
},
meta: { frameTags: [{ name: "Idle", from: 0, to: 3 }] },
}}
/>
</Screen.Filter>
</Screen>
</WidgetArea>
</div>
);
}