diff --git a/README.md b/README.md index ca19361..20097cf 100644 --- a/README.md +++ b/README.md @@ -63,9 +63,10 @@ React Zero-UI uses a hyper-optimized AST resolver in development that scans your Zero-UI CLI -**Pre-requisites:** -* Vite or Next.js (App Router) -* Tailwind V4 Configured. See [Tailwind V4 Installation](https://tailwindcss.com/docs/installation/using-vite) +**Pre-requisites:** + +- Vite or Next.js (App Router) +- Tailwind V4 Configured. See [Tailwind V4 Installation](https://tailwindcss.com/docs/installation/using-vite) ```bash npx create-zero-ui @@ -141,9 +142,10 @@ Sometimes CSS variables are more efficient. React Zero-UI makes it trivial by pa ```diff + Pass `CssVar` to either hook to use CSS variables -useUI(, , CssVar); +useUI(, , CssVar); ``` + automatically adds `--` to the Css Variable **Global CSS Variable:** @@ -200,26 +202,26 @@ React Zero-UI delivers the fastest, simplest, most performant way to handle glob ### ๐Ÿ“š Complete Guide Collection -| Guide | Description | -|-------|-------------| -| [๐Ÿ“š API Reference](/docs/api-reference.md) | Complete API documentation for all hooks and utilities | -| [๐Ÿ“‹ Usage Examples](/docs/usage-examples.md) | Practical patterns and real-world use cases | -| [๐Ÿ”„ Migration Guide](/docs/migration-guide.md) | Step-by-step migration from useState, Context, Redux | -| [๐Ÿ”ง Troubleshooting](/docs/troubleshooting.md) | Common issues and debugging techniques | -| [โ“ FAQ](/docs/faq.md) | Frequently asked questions and answers | -| [๐Ÿงช Experimental Features](/docs/experimental.md) | SSR-safe server component interactivity | +| Guide | Description | +| ------------------------------------------------- | ------------------------------------------------------ | +| [๐Ÿ“š API Reference](/docs/api-reference.md) | Complete API documentation for all hooks and utilities | +| [๐Ÿ“‹ Usage Examples](/docs/usage-examples.md) | Practical patterns and real-world use cases | +| [๐Ÿ”„ Migration Guide](/docs/migration-guide.md) | Step-by-step migration from useState, Context, Redux | +| [๐Ÿ”ง Troubleshooting](/docs/troubleshooting.md) | Common issues and debugging techniques | +| [โ“ FAQ](/docs/faq.md) | Frequently asked questions and answers | +| [๐Ÿงช Experimental Features](/docs/experimental.md) | SSR-safe server component interactivity | ### ๐Ÿ› ๏ธ Setup Guides -| Framework | Guide | -|-----------|-------| +| Framework | Guide | +| ------------------------------------------------ | --------------------------------------- | | [Next.js App Router](/docs/installation-next.md) | Complete Next.js setup with SSR support | -| [Vite + React](/docs/installation-vite.md) | Vite configuration and optimization | +| [Vite + React](/docs/installation-vite.md) | Vite configuration and optimization | ### ๐ŸŽฏ Learn by Example - [๐ŸŽฎ **Live Demo**](https://zero-ui.dev/) - Interactive playground -- [๐Ÿ“Š **Performance Demo**](https://zero-ui.dev/react) - 10k component benchmark +- [๐Ÿ“Š **Performance Demo**](https://zero-ui.dev/react) - 10k component benchmark - [๐Ÿ“ **Demo Source Code**](/examples/demo/) - Complete example project --- diff --git a/docs/api-reference.md b/docs/api-reference.md index 9af4488..6650bca 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -1,4 +1,3 @@ -
# ๐Ÿ“š API Reference @@ -12,6 +11,7 @@ Detailed reference for all hooks, utilities, and configuration options. --- ## ๐Ÿ“š Table of Contents + - [๐Ÿ”จ Core Hooks](#-core-hooks) - [๐ŸŒˆ Utilities](#-utilities) - [๐Ÿงช Experimental APIs](#-experimental-apis) @@ -34,18 +34,18 @@ const [staleValue, setter] = useUI(key, initial, flag?); #### Parameters -| Parameter | Type | Description | -|-----------|------|-------------| -| `key` | `string` | The state key (becomes `data-{key}` attribute) | -| `initial` | `T` | Initial/default value for SSR | -| `flag?` | `typeof CssVar` | Optional: Use CSS variables instead of data attributes | +| Parameter | Type | Description | +| --------- | --------------- | ------------------------------------------------------ | +| `key` | `string` | The state key (becomes `data-{key}` attribute) | +| `initial` | `T` | Initial/default value for SSR | +| `flag?` | `typeof CssVar` | Optional: Use CSS variables instead of data attributes | #### Returns -| Return | Type | Description | -|--------|------|-------------| -| `staleValue` | `T` | Initial value (doesn't update, use for SSR only) | -| `setter` | `GlobalSetterFn` | Function to update the global state | +| Return | Type | Description | +| ------------ | ------------------- | ------------------------------------------------ | +| `staleValue` | `T` | Initial value (doesn't update, use for SSR only) | +| `setter` | `GlobalSetterFn` | Function to update the global state | #### Examples @@ -62,7 +62,7 @@ const [color, setColor] = useUI('primary', '#blue', CssVar); setColor('#red'); // Sets --primary: #red on // Functional updates -setTheme(prev => prev === 'light' ? 'dark' : 'light'); +setTheme((prev) => (prev === 'light' ? 'dark' : 'light')); ``` --- @@ -81,10 +81,10 @@ Same as `useUI`, but affects only the element assigned to `setter.ref`. #### Returns -| Return | Type | Description | -|--------|------|-------------| -| `staleValue` | `T` | Initial value (doesn't update, use for SSR only) | -| `setter` | `ScopedSetterFn` | Function with attached `ref` property | +| Return | Type | Description | +| ------------ | ------------------- | ------------------------------------------------ | +| `staleValue` | `T` | Initial value (doesn't update, use for SSR only) | +| `setter` | `ScopedSetterFn` | Function with attached `ref` property | #### Examples @@ -92,24 +92,22 @@ Same as `useUI`, but affects only the element assigned to `setter.ref`. // Basic scoped usage const [modal, setModal] = useScopedUI('modal', 'closed'); -
+ className="modal-closed:hidden modal-open:block"> Modal content -
+
; // With CSS variables const [blur, setBlur] = useScopedUI('blur', '0px', CssVar); -
+ className="backdrop-blur-[var(--blur)]"> Blurred content -
+; ``` --- @@ -148,10 +146,10 @@ const clickHandler = zeroSSR.onClick(key, values); #### Parameters -| Parameter | Type | Description | -|-----------|------|-------------| -| `key` | `string` | State key (kebab-case required) | -| `values` | `string[]` | Array of values to cycle through | +| Parameter | Type | Description | +| --------- | ---------- | -------------------------------- | +| `key` | `string` | State key (kebab-case required) | +| `values` | `string[]` | Array of values to cycle through | #### Returns @@ -189,13 +187,9 @@ Same as `zeroSSR.onClick`, but affects the closest ancestor with `data-{key}` at ```tsx
- - -
- Modal content -
+ + +
Modal content
``` @@ -214,8 +208,8 @@ activateZeroUiRuntime(variantKeyMap); #### Parameters -| Parameter | Type | Description | -|-----------|------|-------------| +| Parameter | Type | Description | +| ------------ | -------------------------- | -------------------------------------------- | | `variantMap` | `Record` | Generated variant mapping from build process | #### Setup @@ -285,16 +279,13 @@ interface ScopedSetterFn { ## ๐Ÿšจ Limitations & Constraints ### State Key Requirements + - DO NOT USE IMPORTED VARIABLES IN THE STATE KEY - Must be valid HTML attribute names - Kebab-case required: `'sidebar-state'` not `'sidebarState'` - Avoid conflicts with existing data attributes - Must resolve to a non-spaced string: `'sidebar-state'` not `'sidebar State'` -- Must be a local constant that resolves to a string: - - - - +- Must be a local constant that resolves to a string: ### Scoped UI Constraints @@ -325,12 +316,11 @@ Generated variant mapping for runtime activation. ```ts /* AUTO-GENERATED - DO NOT EDIT */ export const bodyAttributes = { - "data-theme": "light", - "data-accent": "violet", - "data-scrolled": "up", - // ... + 'data-theme': 'light', + 'data-accent': 'violet', + 'data-scrolled': 'up', + // ... }; - ``` ### `.zero-ui/styles.css` (Vite) @@ -339,7 +329,7 @@ Generated CSS variants for Vite projects. ```css /* Auto-generated Tailwind variants */ -[data-theme="dark"] .theme-dark\:bg-gray-900 { +[data-theme='dark'] .theme-dark\:bg-gray-900 { background-color: rgb(17 24 39); } /* ... */ @@ -385,14 +375,14 @@ cat .zero-ui/attributes.ts ```tsx // โœ… Good: Descriptive and clear -useUI('theme', 'light') -useUI('sidebar-state', 'collapsed') -useUI('modal-visibility', 'hidden') +useUI('theme', 'light'); +useUI('sidebar-state', 'collapsed'); +useUI('modal-visibility', 'hidden'); // โŒ Avoid: Generic or unclear -useUI('state', 'on') -useUI('x', 'y') -useUI('toggle', 'true') +useUI('state', 'on'); +useUI('x', 'y'); +useUI('toggle', 'true'); ``` ### TypeScript Usage @@ -411,13 +401,13 @@ const [, setModal] = useUI('modal', 'closed'); ```tsx // โœ… Use CSS for conditional rendering -
- Modal content -
+
Modal content
; // โŒ Avoid reading stale values for logic const [modal, setModal] = useUI('modal', 'closed'); -{modal === 'open' && } // Won't work as expected +{ + modal === 'open' && ; +} // Won't work as expected ``` --- @@ -428,4 +418,4 @@ const [modal, setModal] = useUI('modal', 'closed'); [**๐Ÿ“‹ Usage Examples**](./usage-examples.md) | [**๐Ÿ”ง Troubleshooting**](./troubleshooting.md) | [**๐Ÿ”„ Migration Guide**](./migration-guide.md) - \ No newline at end of file + diff --git a/docs/demo.md b/docs/demo.md index 6a4d104..321c4f7 100644 --- a/docs/demo.md +++ b/docs/demo.md @@ -14,10 +14,10 @@ Experience the difference between React re-renders and Zero-UI's instant updates ## ๐ŸŽฏ Interactive Examples -| Demo | Description | Live Link | Source Code | -| -- | -- | -- | -- | -| **๐ŸŽ›๏ธ Interactive Menu** | Side-by-side comparison with render tracker | [Main Demo](https://zero-ui.dev/) | [GitHub](https://zero-ui.dev/react) | -| **โš›๏ธ React Benchmark** | Traditional React render path (10k nodes) | [React 10k](https://zero-ui.dev/react) | [GitHub](https://github.com/react-zero-ui/core/tree/main/examples/demo/src/app/react) | +| Demo | Description | Live Link | Source Code | +| ------------------------- | ------------------------------------------------- | ------------------------------------------ | --------------------------------------------------------------------------------------- | +| **๐ŸŽ›๏ธ Interactive Menu** | Side-by-side comparison with render tracker | [Main Demo](https://zero-ui.dev/) | [GitHub](https://zero-ui.dev/react) | +| **โš›๏ธ React Benchmark** | Traditional React render path (10k nodes) | [React 10k](https://zero-ui.dev/react) | [GitHub](https://github.com/react-zero-ui/core/tree/main/examples/demo/src/app/react) | | **โšก๏ธ Zero-UI Benchmark** | Identical DOM with `data-*` switching (10k nodes) | [Zero-UI 10k](https://zero-ui.dev/zero-ui) | [GitHub](https://github.com/react-zero-ui/core/tree/main/examples/demo/src/app/zero-ui) | > **๐Ÿ“ Full Demo Source:** [Zero Rerender Demo](/examples/demo/) @@ -47,10 +47,10 @@ _Tested on Apple M1 - Chrome DevTools Performance Tab_ | **Nodes Updated** | **React State** | **Zero-UI** | **Speed Improvement** | -| :--: | :--: | :--: | :--: | -| 10,000 | ~50 ms | ~5 ms | **๐Ÿš€ 10ร— faster** | -| 25,000 | ~180 ms | ~15 ms | **๐Ÿš€ 12ร— faster** | -| 50,000 | ~300 ms | ~20 ms | **๐Ÿš€ 15ร— faster** | +| :---------------: | :-------------: | :---------: | :-------------------: | +| 10,000 | ~50 ms | ~5 ms | **๐Ÿš€ 10ร— faster** | +| 25,000 | ~180 ms | ~15 ms | **๐Ÿš€ 12ร— faster** | +| 50,000 | ~300 ms | ~20 ms | **๐Ÿš€ 15ร— faster** | > **๐Ÿ”ฌ Try it yourself:** Re-run these benchmarks using the demo links above with Chrome DevTools. diff --git a/docs/faq.md b/docs/faq.md index 72bc647..2d041db 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -1,5 +1,3 @@ - -
# โ“ Frequently Asked Questions @@ -21,12 +19,14 @@ React Zero-UI is a state management library that eliminates React re-renders for ### How is this different from regular React state? **Traditional React:** + ```tsx const [theme, setTheme] = useState('light'); // Every setState() triggers re-render of component tree ``` **React Zero-UI:** + ```tsx const [, setTheme] = useUI('theme', 'light'); // No re-renders, just flips data-theme="dark" on @@ -47,6 +47,7 @@ Not really! If you know React hooks and Tailwind CSS, you already know 95% of wh ### How much faster is it really? **Benchmarks** (10,000 DOM nodes): + - React state changes: ~50ms - Zero-UI state changes: ~5ms - **Result: 10ร— faster updates** @@ -58,9 +59,10 @@ The more complex your UI, the bigger the performance gain. **Zero-UI core: ~350 bytes** in production (10x smaller than a single svg icon) Compare that to: + - Redux: ~5KB - SVG Icon: ~4KB -So about 10x smaller than a single SVG icon + So about 10x smaller than a single SVG icon ### What about CSS file size? @@ -80,10 +82,10 @@ Zero-UI uses a custom Babel-based resolver that only analyzes **top-level `const Why? Because resolving cross-file imports requires a **full module graph**, accounting for: -* ESM vs CJS interop -* TypeScript vs JavaScript -* Re-exports, namespace imports, aliased paths, dynamic values -* Recursive constant folding across files +- ESM vs CJS interop +- TypeScript vs JavaScript +- Re-exports, namespace imports, aliased paths, dynamic values +- Recursive constant folding across files This problem is **deceptively deep** โ€” even Facebook's [Prepack](https://prepack.io/) abandoned the attempt after years of effort. @@ -107,7 +109,7 @@ Absolutely! Zero-UI is designed for **UI state only**. Use it alongside: ```tsx // โœ… Great combination const [data, setData] = useState(null); // Component state -const { user } = useQuery('user'); // Server state +const { user } = useQuery('user'); // Server state const [, setTheme] = useUI('theme', 'light'); // UI state ``` @@ -151,11 +153,11 @@ useEffect(() => { and tailwind variants are generated by tailwindCSS. ```css - [data-theme="dark"] { +[data-theme='dark'] { background: black; } ``` - + ### Can I use CSS variables? Yes! Pass the `CssVar` flag: @@ -179,7 +181,7 @@ const [, setColor] = useUI('primary', '#blue', CssVar); // Before const [theme, setTheme] = useState('light'); -// After +// After const [, setTheme] = useUI('theme', 'light'); // Note: Don't use the first return value for logic ``` @@ -192,7 +194,7 @@ If context is used for UI state, it's even easier! Just remove the provider: // Before: Need provider, useContext, prop drilling - +; // After: State works everywhere automatically function App() { @@ -222,11 +224,7 @@ It allows interactivity in **server components** without `'use client'` see [exp import { zeroSSR } from '@react-zero-ui/core/experimental'; function ServerThemeToggle() { - return ( - - ); + return ; } ``` @@ -249,22 +247,22 @@ I would not recommend using it in production until the API is stable. Because th **Check these in order:** 1. **PostCSS plugin configured? (Next.js)** + ```js // postcss.config.js module.exports = { - plugins: { - '@react-zero-ui/core/postcss': {}, // Before Tailwind! - tailwindcss: {}, - }, + plugins: { + '@react-zero-ui/core/postcss': {}, // Before Tailwind! + tailwindcss: {}, + }, }; ``` 2. **Tailwind V4 Configured and imported?** ```css - @import "tailwindcss"; + @import 'tailwindcss'; ``` - ### I get "Multiple ref attachments" error Each `useScopedUI` can only attach to one element: @@ -282,8 +280,6 @@ const [, setState2] = useScopedUI('state-2', 'default');
``` - - --- ## ๐ŸŽฏ Best Practices @@ -291,27 +287,30 @@ const [, setState2] = useScopedUI('state-2', 'default'); ### When should I use Zero-UI? **โœ… Perfect for:** + - Theme switching -- Modal/drawer states +- Modal/drawer states - Navigation states - UI toggles and animations - Any visual state that doesn't affect business logic **โŒ Not ideal for:** + - Form data - API responses - Complex business logic - State that needs to trigger side effects - ### Should I use global or scoped state? **Global (`useUI`)** for: + - App-wide state (theme, language) - State that affects multiple components - State you want accessible everywhere **Scoped (`useScopedUI`)** for: + - Component-specific state - State that doesn't affect other components - Better performance for isolated changes @@ -333,7 +332,7 @@ const [, setState2] = useScopedUI('state-2', 'default'); - ๐Ÿ› Report bugs and use cases - ๐Ÿ’ก Share your usage patterns - ๐Ÿค Contribute code or documentation - + --- ## ๐Ÿ“ž Getting Help @@ -344,7 +343,6 @@ const [, setState2] = useScopedUI('state-2', 'default'); 2. **๐Ÿ’ฌ Discussions:** [GitHub Discussions](https://github.com/react-zero-ui/core/discussions) for questions 3. **๐Ÿ› Issues:** [GitHub Issues](https://github.com/react-zero-ui/core/issues) for bugs - ### How do I report a bug? 1. Check existing issues first @@ -355,6 +353,7 @@ const [, setState2] = useScopedUI('state-2', 'default'); ### Can I contribute? **Absolutely!** We welcome: + - ๐Ÿ“ Documentation improvements - ๐Ÿ› Bug fixes - โœจ Feature implementations @@ -372,4 +371,4 @@ See our [Contributing Guide](./CONTRIBUTING.md) to get started. The community is here to help! -
\ No newline at end of file +
diff --git a/docs/internal.md b/docs/internal.md index d9c0d5b..4fe99ea 100644 --- a/docs/internal.md +++ b/docs/internal.md @@ -117,12 +117,12 @@ Everything funnels through **`literalFromNode`**. Think of it as a deterministic ### 3.2 Resolvers -| Helper | Purpose | -| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | -| **`resolveTemplateLiteral`** | Ensures every `${expr}` resolves via `literalFromNode`. | +| Helper | Purpose | +| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| **`resolveTemplateLiteral`** | Ensures every `${expr}` resolves via `literalFromNode`. | | **`resolveLocalConstIdentifier`** | Maps an `Identifier` โžก๏ธ its `const` initializer _iff_ initializer is a local static string/template. Imported bindings rejected explicitly. | -| **`resolveMemberExpression`** | Static walk of `obj.prop`, `obj['prop']`, `obj?.prop`, arrays, numeric indexes, optionalโ€‘chainingโ€ฆ Throws if unresolved. | -| **`literalFromNode`** | Router calling above; memoised (`WeakMap`) per AST node. | +| **`resolveMemberExpression`** | Static walk of `obj.prop`, `obj['prop']`, `obj?.prop`, arrays, numeric indexes, optionalโ€‘chainingโ€ฆ Throws if unresolved. | +| **`literalFromNode`** | Router calling above; memoised (`WeakMap`) per AST node. | Resolvers throw contextual errors via **`throwCodeFrame`** (`@babel/code-frame`). diff --git a/docs/migration-guide.md b/docs/migration-guide.md index 4ca4d51..9e3b5f5 100644 --- a/docs/migration-guide.md +++ b/docs/migration-guide.md @@ -15,40 +15,39 @@ Step-by-step guides for common migration scenarios. ### Basic State Migration **Before (React useState):** + ```tsx import { useState } from 'react'; function ThemeToggle() { const [theme, setTheme] = useState('light'); - + return (
- +
); } ``` **After (React Zero-UI):** + ```tsx import { useUI } from '@react-zero-ui/core'; function ThemeToggle() { const [, setTheme] = useUI('theme', 'light'); - + return (
- +
); } ``` **Key Changes:** + 1. Replace `useState` with `useUI` 2. Replace conditional classNames with Tailwind variants 3. State key becomes a data attribute (`data-theme`) @@ -57,22 +56,19 @@ function ThemeToggle() { ### Modal State Migration **Before:** + ```tsx function App() { const [isModalOpen, setIsModalOpen] = useState(false); - + return ( <> - - + + {isModalOpen && (
- +
)} @@ -82,21 +78,18 @@ function App() { ``` **After:** + ```tsx function App() { const [, setModal] = useUI('modal', 'closed'); - + return ( <> - - + +
- +
@@ -111,49 +104,41 @@ function App() { ### Global Theme Context **Before (Context API):** + ```tsx const ThemeContext = createContext(); function ThemeProvider({ children }) { const [theme, setTheme] = useState('light'); - + return ( -
- {children} -
+
{children}
); } function ThemeToggle() { const { theme, setTheme } = useContext(ThemeContext); - - return ( - - ); + + return ; } ``` **After (React Zero-UI):** + ```tsx // No provider needed! function App({ children }) { - return ( -
- {children} -
- ); + return
{children}
; } function ThemeToggle() { const [, setTheme] = useUI('theme', 'light'); - + return ( - @@ -162,6 +147,7 @@ function ThemeToggle() { ``` **Benefits:** + - โŒ No more context providers - โŒ No more prop drilling - โŒ No re-renders when state changes @@ -174,6 +160,7 @@ function ThemeToggle() { ### Redux Theme Slice **Before (Redux):** + ```tsx // store/themeSlice.ts const themeSlice = createSlice({ @@ -182,37 +169,34 @@ const themeSlice = createSlice({ reducers: { toggleTheme: (state) => { state.value = state.value === 'light' ? 'dark' : 'light'; - } - } + }, + }, }); // Component function ThemeToggle() { - const theme = useSelector(state => state.theme.value); + const theme = useSelector((state) => state.theme.value); const dispatch = useDispatch(); - + return (
- +
); } ``` **After (React Zero-UI):** + ```tsx // No store setup needed! function ThemeToggle() { const [, setTheme] = useUI('theme', 'light'); - + return (
- +
); } @@ -221,35 +205,30 @@ function ThemeToggle() { ### Zustand Store **Before (Zustand):** + ```tsx -const useThemeStore = create((set) => ({ - theme: 'light', - toggleTheme: () => set(state => ({ - theme: state.theme === 'light' ? 'dark' : 'light' - })) -})); +const useThemeStore = create((set) => ({ theme: 'light', toggleTheme: () => set((state) => ({ theme: state.theme === 'light' ? 'dark' : 'light' })) })); function ThemeToggle() { const { theme, toggleTheme } = useThemeStore(); - + return (
- +
); } ``` **After (React Zero-UI):** + ```tsx function ThemeToggle() { const [, setTheme] = useUI('theme', 'light'); - + return (
- @@ -265,42 +244,35 @@ function ThemeToggle() { ### Styled Components with Theme **Before (Styled Components):** + ```tsx const ThemeProvider = styled.div` - background: ${props => props.theme.bg}; - color: ${props => props.theme.text}; + background: ${(props) => props.theme.bg}; + color: ${(props) => props.theme.text}; `; -const theme = { - light: { bg: 'white', text: 'black' }, - dark: { bg: 'black', text: 'white' } -}; +const theme = { light: { bg: 'white', text: 'black' }, dark: { bg: 'black', text: 'white' } }; function App() { const [currentTheme, setCurrentTheme] = useState('light'); - + return ( - + ); } ``` **After (React Zero-UI + Tailwind):** + ```tsx function App() { const [, setTheme] = useUI('theme', 'light'); - + return (
- +
); } @@ -313,15 +285,14 @@ function App() { ### Converting Local State to Global **Before (Local component state):** + ```tsx function Sidebar() { const [isOpen, setIsOpen] = useState(false); - + return (
- +
); } @@ -333,26 +304,21 @@ function Header() { ``` **After (Global state, accessible everywhere):** + ```tsx function Sidebar() { const [, setSidebar] = useUI('sidebar', 'closed'); - + return (
- +
); } function Header() { // Can respond to sidebar state! ๐ŸŽ‰ - return ( -
- Header content -
- ); + return
Header content
; } ``` @@ -374,6 +340,7 @@ npx create-zero-ui ``` Or manual setup: + - [ ] Install `@react-zero-ui/core` - [ ] Configure PostCSS plugin - [ ] Update Tailwind config @@ -416,7 +383,6 @@ const [, setTheme] = useUI('theme', 'lite'); // typo! const [, setTheme] = useUI('theme', 'light'); // matches theme-light: ``` - --- ### 3. **No Imported State Keys (Yet)** @@ -437,32 +403,32 @@ const [, setTheme] = useUI(THEME_KEY, 'dark'); ``` > ๐Ÿง  We're working on support for imported bindings once Next.js exposes a plugin API for Turbopack. Until then, stick with top-level `const` literals. - - ### 4. Don't Read Stale Values ```tsx // โŒ Don't use returned value for logic const [theme, setTheme] = useUI('theme', 'light'); -if (theme === 'dark') { /* Won't work! */ } +if (theme === 'dark') { + /* Won't work! */ +} // โœ… Use CSS classes for visual state -
Only visible in light mode
+
Only visible in light mode
; ``` --- ## ๐Ÿ“Š Before/After Comparison -| Aspect | Before (Traditional) | After (React Zero-UI) | -|--------|---------------------|----------------------| -| **Bundle Size** | +5KB (Redux) / +2KB (Context) | +350 bytes | -| **Re-renders** | Every state change | Zero | -| **Performance** | Slower with scale | Constant fast | -| **Setup** | Complex (store, providers) | Simple (one hook) | -| **Global Access** | Prop drilling / Context | Tailwind variants anywhere | -| **SSR** | Hydration mismatches | Perfect SSR | +| Aspect | Before (Traditional) | After (React Zero-UI) | +| ----------------- | ----------------------------- | -------------------------- | +| **Bundle Size** | +5KB (Redux) / +2KB (Context) | +350 bytes | +| **Re-renders** | Every state change | Zero | +| **Performance** | Slower with scale | Constant fast | +| **Setup** | Complex (store, providers) | Simple (one hook) | +| **Global Access** | Prop drilling / Context | Tailwind variants anywhere | +| **SSR** | Hydration mismatches | Perfect SSR | --- @@ -474,4 +440,4 @@ Your app should now be faster, simpler, and more maintainable. [**๐Ÿš€ Next: Usage Examples**](./usage-examples.md) | [**๐Ÿ“– API Reference**](../README.md#-api-reference) -
\ No newline at end of file + diff --git a/docs/usage-examples.md b/docs/usage-examples.md index 072cff8..3474222 100644 --- a/docs/usage-examples.md +++ b/docs/usage-examples.md @@ -21,12 +21,11 @@ import { useUI } from '@react-zero-ui/core'; function ThemeToggle() { const [theme, setTheme] = useUI('theme', 'light'); - + return ( - ); @@ -34,10 +33,9 @@ function ThemeToggle() { ``` **Tailwind usage anywhere in your app:** + ```html -
- Content that responds to theme -
+
Content that responds to theme
``` ### 2. Modal State Management @@ -47,20 +45,16 @@ import { useUI } from '@react-zero-ui/core'; function App() { const [, setModal] = useUI('modal', 'closed'); - + return ( <> - - + + {/* Modal backdrop */}

Modal Content

- +
@@ -77,16 +71,16 @@ type TabState = 'home' | 'about' | 'contact'; function Navigation() { const [activeTab, setActiveTab] = useUI('nav-tab', 'home'); - + const tabs = [ { id: 'home', label: 'Home' }, { id: 'about', label: 'About' }, - { id: 'contact', label: 'Contact' } + { id: 'contact', label: 'Contact' }, ] as const; - + return (