Skip to content

Commit 0cde781

Browse files
committed
feat: added demo website
1 parent ad8626c commit 0cde781

File tree

100 files changed

+5824
-3867
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+5824
-3867
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ on:
44
push:
55
branches: [main]
66
paths:
7-
- "packages/**"
8-
- ".github/workflows/ci.yml"
9-
- "scripts/**"
7+
- 'packages/**'
8+
- '.github/workflows/ci.yml'
9+
- 'scripts/**'
1010
pull_request:
1111

1212
concurrency:

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Release
22

33
on:
44
workflow_run:
5-
workflows: ["CI"]
5+
workflows: ['CI']
66
types: [completed]
77
branches: [main]
88
workflow_dispatch:

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ dist/
55
coverage/
66
test-results/
77
.pnpm-store/
8+
package-lock.json
89

910
# logs / temp files
1011
npm-debug.log*
@@ -24,3 +25,5 @@ todo.md
2425

2526
# keep these files
2627
!next-env.d.ts
28+
29+

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/examples

.prettierrc.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"semi": true,
3+
"trailingComma": "es5",
4+
"singleQuote": true,
5+
"tabWidth": 2,
6+
"useTabs": true,
7+
"printWidth": 160,
8+
"endOfLine": "lf",
9+
"arrowParens": "avoid",
10+
"bracketSpacing": true,
11+
"objectWrap": "collapse",
12+
"bracketSameLine": true,
13+
"embeddedLanguageFormatting": "auto",
14+
"singleAttributePerLine": true
15+
}

.release-please-config.json

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
{
2-
"packages": {
3-
"packages/core": {
4-
"package-name": "@austinserb/react-zero-ui",
5-
"release-type": "node"
6-
},
7-
"packages/cli": {
8-
"package-name": "create-zero-ui",
9-
"release-type": "node"
10-
}
11-
},
12-
"monorepo-tags": true,
13-
"include-component-in-tag": true
14-
}
2+
"packages": {
3+
"packages/core": { "package-name": "@austinserb/react-zero-ui", "release-type": "node" },
4+
"packages/cli": { "package-name": "create-zero-ui", "release-type": "node" }
5+
},
6+
"monorepo-tags": true,
7+
"include-component-in-tag": true
8+
}

AGENTS.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Guidelines for AI Agents in this Repo
2+
3+
This repository contains **React Zero-UI**, a library for global UI state without React re-renders.
4+
Use these tips when working with the codebase or generating examples.
5+
6+
## How React Zero-UI works
7+
8+
1. `useUI()` writes to `document.body.dataset` using keys you specify (e.g. `theme``data-theme`).
9+
2. Build tooling scans for all keys and values, generating CSS variants for each.
10+
3. When a setter is called, the corresponding body attribute changes instantly with no React re-render.
11+
12+
## Best practices
13+
14+
- Only use `useUI` for UI-only state (themes, flags, etc.).
15+
- Prefer kebab-case keys (`sidebar-open`) so generated variants are predictable.
16+
- Always pass a default value to `useUI(key, defaultValue)` to avoid flashes during SSR.
17+
- Mutate the state anywhere in the app: `const [, setTheme] = useUI('theme', 'light');` then call `setTheme('dark')`.
18+
- Compose Tailwind classes anywhere with the pattern `key-value:` like `theme-dark:bg-black`.

README.md

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# React Zero-UI
1+
# React Zero-UI (Beta)
22

3-
**Instant UI state updates. ZERO React re-renders. ZERO runtime overhead.** Update the UI instantly, manage global UI state from anywhere. No prop drilling. get started with one command in your existing React app. ```npx create-zero-ui```
3+
**Instant UI state updates. ZERO React re-renders. ZERO runtime overhead.** Update the UI instantly, manage global UI state from anywhere. No prop drilling. get started with one command in your existing React app. `npx create-zero-ui`
44

55
[![npm version](https://img.shields.io/npm/v/@austinserb/react-zero-ui)](https://www.npmjs.com/package/@austinserb/react-zero-ui)
66
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
@@ -14,7 +14,7 @@ Traditional React state triggers RE-renders for every UI change. Switching theme
1414
Zero-UI bypasses React entirely for pure UI state. Instead of re-renders, it:
1515

1616
- Pre-renders CSS styles and keeps them in the DOM
17-
- For state changes it flips a ```data-*``` attribute key.
17+
- For state changes it flips a `data-*` attribute key.
1818
- Thats it.
1919

2020
**Result:** UI updates that are 10-50x faster.
@@ -23,11 +23,11 @@ Zero-UI bypasses React entirely for pure UI state. Instead of re-renders, it:
2323

2424
Apple M1
2525

26-
| Nodes | React State | Zero-UI | Improvement |
27-
|-------|------------------|---------|-------------|
28-
| 1,000 | ~50ms | ~5ms | 10x faster |
29-
| 5,000 | ~180ms | ~15ms | 12x faster |
30-
| 10,000 | ~400ms | ~20ms | 20x faster |
26+
| Nodes | React State | Zero-UI | Improvement |
27+
| ------ | ----------- | ------- | ----------- |
28+
| 1,000 | ~50ms | ~5ms | 10x faster |
29+
| 5,000 | ~180ms | ~15ms | 12x faster |
30+
| 10,000 | ~400ms | ~20ms | 20x faster |
3131

3232
## Quick Start
3333

@@ -36,7 +36,7 @@ Apple M1
3636
CLI script - in your existing Next or Vite App's root:
3737

3838
```bash
39-
npx create-zero-ui
39+
npx create-zero-ui
4040
```
4141

4242
## Manual Installation
@@ -49,34 +49,34 @@ npm install @austinserb/react-zero-ui
4949

5050
**Prerequisites:** Tailwind v4 must be initialized. [tailwind set up ]("tailwind.com")
5151

52-
5352
#### Vite
5453

5554
```js
5655
// vite.config.*
5756
import { zeroUIPlugin } from '@austinserb/react-zero-ui/vite';
5857

5958
export default {
60-
//*REMOVE TAILWIND PLUGIN* Zero-UI extends tailwinds plug-in
61-
plugins: [zeroUIPlugin()]
62-
}
59+
//*REMOVE TAILWIND PLUGIN* Zero-UI extends tailwinds plug-in
60+
plugins: [zeroUIPlugin()],
61+
};
6362
```
6463

6564
#### Next.js
6665

6766
#### 1. Spread bodyAttributes on `<body>` in Layout
6867

6968
```jsx
70-
import { bodyAttributes } from "@zero-ui/attributes";
69+
import { bodyAttributes } from '@zero-ui/attributes';
7170
//or
72-
import { bodyAttributes } from "../.zero-ui/attributes";
71+
import { bodyAttributes } from '../.zero-ui/attributes';
7372

7473
export default function RootLayout({ children }) {
75-
return (
76-
<html>
77-
<body {...bodyAttributes}>{children}</body>
78-
</html>
79-
)}
74+
return (
75+
<html>
76+
<body {...bodyAttributes}>{children}</body>
77+
</html>
78+
);
79+
}
8080
```
8181

8282
#### 2. Add PostCSS Plugin
@@ -110,7 +110,7 @@ function ThemeToggle() {
110110
**Consume the state in any component with tailwind!**
111111
112112
```jsx
113-
className="theme-light:bg-white theme-dark:bg-black"
113+
className = 'theme-light:bg-white theme-dark:bg-black';
114114
```
115115
116116
**Mutate the state in any component!**
@@ -126,24 +126,28 @@ function UnrelatedPage()
126126
127127
**Use with complex Tailwind Variants**
128128
129-
130129
```jsx
131-
clasName="md:theme-dark:bg-black md:peer-checked:theme-light:hidden"
130+
clasName = 'md:theme-dark:bg-black md:peer-checked:theme-light:hidden';
132131
```
133132
134133
## How It Works
135134
136135
1. **State Store**: The `useUI` hook writes to `data-*` attributes on the `<body>` tag instead of React state
136+
137137
```html
138-
<body data-theme="dark" data-accent="blue" data-sidebar="open">
138+
<body
139+
data-theme="dark"
140+
data-accent="blue"
141+
data-sidebar="open"></body>
139142
```
140143
141144
2. **Babel Transform**: Automatically detects all `useUI` variants in your code during build
142145
143146
3. **PostCSS Plugin**: Generates Tailwind variant classes for every detected state
147+
144148
```css
145149
.theme-dark\:bg-gray-900 {
146-
background-color: rgb(17 24 39);
150+
background-color: rgb(17 24 39);
147151
}
148152
```
149153
@@ -163,7 +167,7 @@ const [staleValue, setValue] = useUI('theme', 'light');
163167
- `defaultValue`: Initial value if not set
164168
- Returns: `[staleValue, setValue]`
165169
166-
**note:** normaly used as const ```const [,setValue]=useUI()``` to denote that the value is stale and will not update
170+
**note:** normaly used as const `const [,setValue]=useUI()` to denote that the value is stale and will not update
167171
168172
### Tailwind Variants
169173
@@ -191,7 +195,7 @@ Use the pattern `{key}-{value}:` as a Tailwind variant:
191195
2. **Not for business logic**: Keep using React state for data that affects logic
192196
3. **Consistent naming**: Prefer kebab-case for keys (`sidebar-state`, not `sidebarState`)
193197
4. **Default values**: Always provide default value for
194-
```useUI('key', 'value')``` to avoid FOUC.
198+
`useUI('key', 'value')` to avoid FOUC.
195199
196200
## Contributing
197201

eslint.config.js

Lines changed: 40 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -3,75 +3,53 @@ import js from '@eslint/js';
33
import nodePlugin from 'eslint-plugin-node';
44

55
const nodeGlobals = {
6-
require: 'readonly',
7-
module: 'readonly',
8-
exports: 'readonly',
9-
__dirname: 'readonly',
10-
__filename: 'readonly',
11-
process: 'readonly',
12-
console: 'readonly',
13-
Buffer: 'readonly',
14-
setTimeout: 'readonly',
15-
setInterval: 'readonly',
16-
clearTimeout: 'readonly',
17-
clearInterval: 'readonly',
6+
require: 'readonly',
7+
module: 'readonly',
8+
exports: 'readonly',
9+
__dirname: 'readonly',
10+
__filename: 'readonly',
11+
process: 'readonly',
12+
console: 'readonly',
13+
Buffer: 'readonly',
14+
setTimeout: 'readonly',
15+
setInterval: 'readonly',
16+
clearTimeout: 'readonly',
17+
clearInterval: 'readonly',
1818
};
1919

2020
const browserGlobals = {
21-
window: 'readonly',
22-
document: 'readonly',
23-
navigator: 'readonly',
24-
requestAnimationFrame: 'readonly',
25-
cancelAnimationFrame: 'readonly',
26-
setTimeout: 'readonly',
27-
setInterval: 'readonly',
28-
clearTimeout: 'readonly',
29-
clearInterval: 'readonly',
30-
console: 'readonly',
21+
window: 'readonly',
22+
document: 'readonly',
23+
navigator: 'readonly',
24+
requestAnimationFrame: 'readonly',
25+
cancelAnimationFrame: 'readonly',
26+
setTimeout: 'readonly',
27+
setInterval: 'readonly',
28+
clearTimeout: 'readonly',
29+
clearInterval: 'readonly',
30+
console: 'readonly',
3131
};
3232

3333
export default [
34-
/* 1 - never lint generated / vendor files */
35-
{
36-
ignores: [
37-
'**/node_modules/**',
38-
'**/dist/**',
39-
'**/.next/**',
40-
'**/*.test.*',
41-
'**/*.spec.*',
42-
'tests/**',
43-
'eslint.config.js',
44-
],
45-
},
34+
/* 1 - never lint generated / vendor files */
35+
{ ignores: ['**/node_modules/**', '**/dist/**', '**/.next/**', '**/*.test.*', '**/*.spec.*', 'tests/**', 'eslint.config.js'] },
4636

47-
/* 2 - baseline rules */
48-
js.configs.recommended,
37+
/* 2 - baseline rules */
38+
js.configs.recommended,
4939

50-
/* 3 - CommonJS (*.cjs) */
51-
{
52-
files: ['**/*.cjs'],
53-
plugins: { node: nodePlugin },
54-
languageOptions: {
55-
ecmaVersion: 'latest',
56-
sourceType: 'script',
57-
globals: nodeGlobals,
58-
},
59-
rules: {
60-
'node/no-unsupported-features/es-syntax': 'off',
61-
},
62-
},
40+
/* 3 - CommonJS (*.cjs) */
41+
{
42+
files: ['**/*.cjs'],
43+
plugins: { node: nodePlugin },
44+
languageOptions: { ecmaVersion: 'latest', sourceType: 'script', globals: nodeGlobals },
45+
rules: { 'node/no-unsupported-features/es-syntax': 'off' },
46+
},
6347

64-
/* 4 - ES-module / browser (*.js) */
65-
{
66-
files: ['**/*.js'],
67-
plugins: { node: nodePlugin },
68-
languageOptions: {
69-
ecmaVersion: 'latest',
70-
sourceType: 'module',
71-
globals: { ...nodeGlobals, ...browserGlobals },
72-
},
73-
rules: {
74-
'node/no-unsupported-features/es-syntax': 'off',
75-
},
76-
},
48+
/* 4 - ES-module / browser (*.js) */
49+
{
50+
files: ['**/*.js'],
51+
plugins: { node: nodePlugin },
52+
languageOptions: { ecmaVersion: 'latest', sourceType: 'module', globals: { ...nodeGlobals, ...browserGlobals } },
53+
rules: { 'node/no-unsupported-features/es-syntax': 'off' },
54+
},
7755
];

examples/demo/.prettierignore

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# package artifacts
2+
node_modules/
3+
.next/
4+
dist/
5+
coverage/
6+
test-results/
7+
.pnpm-store/
8+
package-lock.json
9+
10+
# logs / temp files
11+
npm-debug.log*
12+
yarn-error.log*
13+
.DS_Store
14+
**/playwright-report/
15+
16+
# IDE/editor
17+
.vscode/
18+
19+
# tarballs produced during local tests
20+
*.tgz
21+
22+
# local scratch files
23+
t.py
24+
todo.md
25+
26+
# keep these files
27+
!next-env.d.ts

0 commit comments

Comments
 (0)