Skip to content

Commit 2c46dc6

Browse files
committed
Modern state management following TanStack/Zustand patterns. Minimal base styles for full developer control
1 parent cb11fc3 commit 2c46dc6

File tree

8 files changed

+480
-201
lines changed

8 files changed

+480
-201
lines changed

examples/vanilla/toolbar-demo/example-app/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ <h2>Try This</h2>
2929
<li>Click "Login" to authenticate with WordPress</li>
3030
<li>Click "Fetch Posts" to load posts from WordPress</li>
3131
<li>Click a post to view toolbar controls</li>
32-
<li>Use the toolbar at the bottom to preview or edit</li>
32+
<li>Check the state below to see how it updates</li>
3333
</ol>
3434
</section>
3535
</main>

examples/vanilla/toolbar-demo/example-app/src/main.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ const renderer = new VanillaRenderer(toolbar, 'toolbar');
2222
// Register Custom Nodes
2323
// ============================================================================
2424

25-
// Simple home button
2625
toolbar.register('home', 'Home', () => {
27-
console.log('Navigate to home');
2826
window.location.href = '/';
2927
});
3028

packages/toolbar/README.md

Lines changed: 73 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ A lightweight, performant toolbar for headless WordPress. Works with any JavaScr
77
## Features
88

99
- 🎯 **Framework Agnostic** - Works with React, Vue, Svelte, or vanilla JavaScript
10-
-**Zero Dependencies** - Lightweight and fast
10+
-**Zero Dependencies** - Core library has no dependencies
1111
- 🔒 **Type Safe** - Full TypeScript support
12-
- 🎨 **Themeable** - CSS custom properties for styling
13-
- 🌓 **Dark Mode** - Automatic support
12+
- 🪝 **React Hooks** - First-class React support with hooks
13+
- 🎨 **Headless UI** - Full control over rendering and styling
1414

1515
## Installation
1616

@@ -20,28 +20,55 @@ npm install @wpengine/hwp-toolbar
2020

2121
## Quick Start
2222

23+
### Vanilla JavaScript
24+
2325
```javascript
2426
import { Toolbar, VanillaRenderer } from '@wpengine/hwp-toolbar';
2527
import '@wpengine/hwp-toolbar/styles';
2628

27-
// Create toolbar
2829
const toolbar = new Toolbar({
2930
onPreviewChange: (enabled) => {
3031
console.log('Preview mode:', enabled);
3132
}
3233
});
3334

34-
// Set WordPress context
3535
toolbar.setWordPressContext({
3636
user: { id: 1, name: 'Admin' },
3737
site: { url: 'https://example.com', adminUrl: 'https://example.com/wp-admin' },
3838
post: { id: 123, title: 'Hello World', type: 'post', status: 'draft', slug: 'hello-world' }
3939
});
4040

41-
// Render
4241
const renderer = new VanillaRenderer(toolbar, 'toolbar');
4342
```
4443

44+
### React (Recommended)
45+
46+
```tsx
47+
import { Toolbar } from '@wpengine/hwp-toolbar';
48+
import { useToolbar } from '@wpengine/hwp-toolbar/react';
49+
50+
const toolbar = new Toolbar({
51+
onPreviewChange: (enabled) => {
52+
console.log('Preview mode:', enabled);
53+
}
54+
});
55+
56+
function MyToolbar() {
57+
const { state, nodes } = useToolbar(toolbar);
58+
59+
return (
60+
<div className="toolbar">
61+
{nodes.map(node => (
62+
<button key={node.id} onClick={node.onClick}>
63+
{typeof node.label === 'function' ? node.label() : node.label}
64+
</button>
65+
))}
66+
{state.user && <span>User: {state.user.name}</span>}
67+
</div>
68+
);
69+
}
70+
```
71+
4572
## API
4673

4774
### Toolbar
@@ -122,34 +149,57 @@ Available variables:
122149
- `--hwp-toolbar-primary-hover` - Primary button hover
123150
- And more...
124151
125-
## Framework Examples
152+
## React Hooks API
153+
154+
### `useToolbar(toolbar)`
126155
127-
### React
156+
Returns both state and nodes in a single hook:
128157
129158
```tsx
130-
import { useEffect, useRef } from 'react';
131-
import { Toolbar, VanillaRenderer } from '@wpengine/hwp-toolbar';
159+
import { useToolbar } from '@wpengine/hwp-toolbar/react';
160+
161+
function MyToolbar() {
162+
const { state, nodes } = useToolbar(toolbar);
163+
// Full control over rendering
164+
}
165+
```
166+
167+
### `useToolbarState(toolbar)`
132168
133-
function WordPressToolbar({ user, post, site }) {
134-
const ref = useRef<HTMLDivElement>(null);
169+
Subscribe to toolbar state only:
135170
136-
useEffect(() => {
137-
if (!ref.current) return;
171+
```tsx
172+
import { useToolbarState } from '@wpengine/hwp-toolbar/react';
173+
174+
function UserDisplay() {
175+
const state = useToolbarState(toolbar);
176+
return <div>{state.user?.name}</div>;
177+
}
178+
```
138179
139-
const toolbar = new Toolbar();
140-
toolbar.setWordPressContext({ user, post, site });
141-
const renderer = new VanillaRenderer(toolbar, ref.current);
180+
### `useToolbarNodes(toolbar)`
142181
143-
return () => {
144-
renderer.destroy();
145-
toolbar.destroy();
146-
};
147-
}, [user, post, site]);
182+
Subscribe to visible nodes only:
148183
149-
return <div ref={ref} />;
184+
```tsx
185+
import { useToolbarNodes } from '@wpengine/hwp-toolbar/react';
186+
187+
function ToolbarButtons() {
188+
const nodes = useToolbarNodes(toolbar);
189+
return (
190+
<>
191+
{nodes.map(node => (
192+
<button key={node.id} onClick={node.onClick}>
193+
{typeof node.label === 'function' ? node.label() : node.label}
194+
</button>
195+
))}
196+
</>
197+
);
150198
}
151199
```
152200
201+
## Framework Examples
202+
153203
### Vue
154204
155205
```vue

packages/toolbar/package.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
"types": "./dist/index.d.ts",
1111
"default": "./dist/index.js"
1212
},
13+
"./react": {
14+
"types": "./dist/react.d.ts",
15+
"default": "./dist/react.js"
16+
},
1317
"./styles": "./src/toolbar.css"
1418
},
1519
"files": [
@@ -31,7 +35,17 @@
3135
],
3236
"author": "WP Engine",
3337
"license": "BSD-0-Clause",
38+
"peerDependencies": {
39+
"react": "^18.0.0 || ^19.0.0"
40+
},
41+
"peerDependenciesMeta": {
42+
"react": {
43+
"optional": true
44+
}
45+
},
3446
"devDependencies": {
47+
"@types/react": "^18.3.0",
48+
"react": "^18.3.1",
3549
"typescript": "^5.8.3"
3650
},
3751
"engines": {

0 commit comments

Comments
 (0)