@zuzjs/ui
v1.1.6
Published
ZuzJS UI Library
Readme
@zuzjs/ui
The @zuzjs/ui library provides a collection of reusable components and blocks designed to streamline your development process. It also includes an automatic CSS generator to help you maintain consistent styling across your application.
Features
- Components: A variety of pre-built UI components to speed up your development.
- Blocks: Modular blocks that can be easily integrated into your projects.
- Auto CSS Generator: Automatically generates CSS to ensure consistent and maintainable styles.
Installation
To install the @zuzjs/ui library, use the following command:
npm install @zuzjs/uiUsage
Import the components and blocks you need and start building your UI:
import { Box, Button, Text } from '@zuzjs/ui';
function App() {
return (
<Box as={`w:100 h:100 bg:red`}>
<Button as={`s:18 bold tac`}>Click Me</Button>
<Text as={`s:18 tac`}>Hello World!</Text>
</Box>
);
}The auto CSS generator will handle the styling for you, ensuring a cohesive look and feel.
Animation Examples
1) CSS Scroll Scenes (No TimelineProvider Required)
Use useScrollScenes for scroll-driven animations that are generated as CSS keyframes.
import { Flex, Text, useScrollScenes } from "@zuzjs/ui";
export default function Landing() {
const scenes = useScrollScenes({
id: "landing",
tracks: {
heroHeadline: {
keyframes: [
{ at: 0, y: "0" },
{ at: 0.33, y: "-1lh" }
],
easing: "var(--spring)"
}
},
scenes: {
hero3: { start: 0.62, inEnd: 0.69, outStart: 0.83, end: 0.90 },
hero4: { start: 0.83, inEnd: 0.90, outStart: 1, end: 1, outY: "0", outOpacity: 1 }
}
});
return (
<Flex cols className={scenes.scopeClass} style={{ height: "600vh" }}>
<Flex as="sticky top:0 h:100vh" className={scenes.className("hero3")}>
<Text className={scenes.className("heroHeadline")}>Animated with CSS scene track</Text>
</Flex>
<Flex as="sticky top:0 h:100vh" className={scenes.className("hero4")}>
<Text>Second scene</Text>
</Flex>
</Flex>
);
}Notes:
TimelineProvideris not required when a page uses onlyuseScrollScenesclasses.- For build-time CSS extraction into
src/app/css/zuz.scss, pass a literal object config touseScrollScenes(...).
2) TimelineProvider + timeline Prop (Existing Engine)
Use this mode when you want layer-based timeline bindings and anchor syntax.
import { Box, TimelineProvider } from "@zuzjs/ui";
export default function Hero() {
return (
<TimelineProvider timeline={{ mode: "timeline", interpolate: true, lerpFactor: 0.08 }}>
<Box timelineRoot as="h:300vh">
<Box
timeline={{
id: "hero",
keyframes: [{ start: 0, end: 0.33, y: [0, "-1lh", "$spring"] }]
}}
>
Timeline layer animation
</Box>
</Box>
</TimelineProvider>
);
}Calendar and DatePicker
Recent behavior updates:
- Month navigation now triggers
CalendaronChangein single-date mode. onChangenow receives metadata so you can detect whether the change came from day selection or month navigation.- When navigating months with
disabledDates, the component finds the nearest selectable date in that month instead of re-selecting a disabled day. DatePickerstays open during month navigation and closes on explicit day selection.
Calendar Example (Single Date)
import { Calendar } from "@zuzjs/ui";
import { useState } from "react";
export default function CalendarExample() {
const [selected, setSelected] = useState<Date | null>(new Date());
return (
<Calendar
value={selected}
disabledDates={[
"2026-05-15",
"2026-05-16",
new Date(2026, 4, 20),
]}
onChange={(date, meta) => {
setSelected(date);
if (meta?.source === "month") {
console.log("Month changed", date);
return;
}
console.log("Day selected", date);
}}
/>
);
}DatePicker Example (Month Navigation + Disabled Dates)
import { DatePicker } from "@zuzjs/ui";
import { useState } from "react";
export default function DatePickerExample() {
const [value, setValue] = useState<Date | null>(new Date());
return (
<DatePicker
dateValue={value}
disabledDates={[
"2026-05-15",
"2026-05-16",
"2026-05-17",
]}
onDateChange={(nextDate) => {
setValue(nextDate);
console.log("DatePicker changed", nextDate);
}}
/>
);
}Notes:
- In range mode (
range={true}), month navigation does not emitonChange; range selection continues viaonRangeChange. onChange(date, { source: "month" })can returndate = nullif the target month has no selectable dates after applying min/max anddisabledDates.
Documentation
Documention in progress.
AI Skill Guide
For AI-assisted UI generation with this library (Copilot/Claude), use:
| File | Purpose |
|---|---|
| AI_SKILL.md | Full as prop grammar, responsive/pseudo syntax, authoring rules |
| AGENTS.md | Copilot agent entry — points to AI_SKILL.md |
| CLAUDE.md | Claude entry — aliases AGENTS.md |
| component-schema.json | Machine-readable component + prop index for programmatic agent consumption |
| PROMPT_PRESETS.md | Copy-paste prompt templates for common patterns (tables, forms, drawers) |
These files define component prop resolution rules, as syntax, shorthand utility classes, and generation constraints.
License
This project is licensed under the MIT License.
