@xzibit/ui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/LICENSE +21 -0
- package/README.md +173 -0
- package/dist/index.cjs +555 -0
- package/dist/index.d.cts +153 -0
- package/dist/index.d.ts +153 -0
- package/dist/index.js +524 -0
- package/package.json +61 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@xzibit/ui` are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/) loosely; versioning follows [SemVer](https://semver.org/).
|
|
4
|
+
|
|
5
|
+
## [0.1.0] — 2026-05-22
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
Initial release. Implements DESIGN-STANDARD.md v2.3.1 §Top Bar canonical chrome.
|
|
10
|
+
|
|
11
|
+
- **`<TopBar />`** — universal 44px fixed top bar (composes everything below)
|
|
12
|
+
- **`<BackToLauncher />`** — chevron + Xzibit X logo + "Xzibit Apps" anchor as one click target; cross-deployment navigation to https://xzibit-apps.vercel.app
|
|
13
|
+
- **`<AppsDropdown />`** — sectioned + within-section alphabetical apps dropdown; fetches `/api/me/apps`; loading skeleton + empty state + error state; Esc + outside-click close; focus return on close
|
|
14
|
+
- **`<XzibitMark />`** — Xzibit X brand mark as inline SVG; any size, any pixel density; native black background stamp
|
|
15
|
+
- **`useApps()`** — React hook fetching `/api/me/apps` with loading + error + refetch; same-origin per-app endpoint pattern
|
|
16
|
+
- **CSS variable theming** — components reference `var(--xz-charcoal, ...)`, `var(--xz-teal, ...)`, etc. with hex fallbacks; recommended companion `@xzibit/tokens` for full token surface
|
|
17
|
+
|
|
18
|
+
### Not yet included (planned for v0.2+)
|
|
19
|
+
|
|
20
|
+
- **`<Modal />`** — wrapper around `@radix-ui/react-dialog` per DESIGN-STANDARD §Modal / Dialog
|
|
21
|
+
- **`<Toast />`** + `useToast()` — wrapper around `sonner` per DESIGN-STANDARD §Toast / Notification
|
|
22
|
+
- **Animation tokens / motion** — pending DESIGN-STANDARD §Motion
|
|
23
|
+
|
|
24
|
+
### Reference implementation
|
|
25
|
+
|
|
26
|
+
`xzibit-apps/erp-overview` SHA `6f1a5b5+` is the canonical reference for the v0.1 component behavior. ERP Overview's local `TopBar.tsx` will be the first migrate-to-shared candidate when this package publishes (eat-our-own-dog-food).
|
|
27
|
+
|
|
28
|
+
## Authority chain
|
|
29
|
+
|
|
30
|
+
This package version matches `_portfolio/CONVENTIONS/DESIGN-STANDARD.md` v2.3.1. When DESIGN-STANDARD bumps, this package bumps to match within ~1 week.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Xzibit Apps
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# @xzibit/ui
|
|
2
|
+
|
|
3
|
+
Shared chrome components for the Xzibit Apps portfolio. Single source of truth — tweak once, every app picks it up on next deploy.
|
|
4
|
+
|
|
5
|
+
**v0.1 scope:** `TopBar`, `BackToLauncher`, `AppsDropdown`, `XzibitMark`, `useApps` hook. Modal + Toast wrappers (Sonner / Radix Dialog) deferred to v0.2.
|
|
6
|
+
|
|
7
|
+
**Stewarded by:** Xzibit Apps Design Standards Cowork. When DESIGN-STANDARD.md changes (currently v2.3.1), this package bumps to match.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @xzibit/ui
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Peer dependencies: `react@^18`, `react-dom@^18`.
|
|
18
|
+
|
|
19
|
+
(Recommended companion: `@xzibit/tokens` for CSS variable values — without it, components fall back to inline hex defaults.)
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Use
|
|
24
|
+
|
|
25
|
+
### Top bar — drop-in chrome for every Xzibit App
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
// src/app/layout.tsx
|
|
29
|
+
import { TopBar } from '@xzibit/ui';
|
|
30
|
+
import '@xzibit/tokens/tokens.css'; // optional but recommended
|
|
31
|
+
|
|
32
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
33
|
+
return (
|
|
34
|
+
<html lang="en">
|
|
35
|
+
<body>
|
|
36
|
+
<TopBar
|
|
37
|
+
appName="ERP Overview"
|
|
38
|
+
buildSha={process.env.VERCEL_GIT_COMMIT_SHA?.slice(0, 7)}
|
|
39
|
+
buildTimestamp="22 May 2026, 5:03 pm AEST"
|
|
40
|
+
/>
|
|
41
|
+
<main id="main" style={{ marginTop: 44 }}>
|
|
42
|
+
{children}
|
|
43
|
+
</main>
|
|
44
|
+
</body>
|
|
45
|
+
</html>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
That's it. The bar renders:
|
|
51
|
+
|
|
52
|
+
- Back-to-launcher anchor (chevron + Xzibit X logo + "Xzibit Apps" text)
|
|
53
|
+
- Vertical separator
|
|
54
|
+
- App wordmark (teal dot + your app name)
|
|
55
|
+
- Vertical separator
|
|
56
|
+
- Apps dropdown (fetches `/api/me/apps`, sectioned + within-section alphabetical)
|
|
57
|
+
- Build badge (SHA + timestamp on right edge)
|
|
58
|
+
|
|
59
|
+
### `/api/me/apps` endpoint required
|
|
60
|
+
|
|
61
|
+
`AppsDropdown` calls `GET /api/me/apps` (same-origin) for the cross-app navigation list. Each consuming app must expose this endpoint per CODING-STANDARDS §6.3:
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
// src/app/api/me/apps/route.ts
|
|
65
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
66
|
+
import { createAdminClient } from '@/lib/supabase/admin';
|
|
67
|
+
import { authenticateUser } from '@/lib/auth-middleware';
|
|
68
|
+
|
|
69
|
+
export async function GET(request: NextRequest) {
|
|
70
|
+
try {
|
|
71
|
+
const { user, error: authError } = await authenticateUser(request);
|
|
72
|
+
if (authError || !user) {
|
|
73
|
+
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const supabase = createAdminClient();
|
|
77
|
+
const { data, error } = await supabase
|
|
78
|
+
.from('apps')
|
|
79
|
+
.select('name, url, description, section, section_order')
|
|
80
|
+
.order('section_order', { ascending: true });
|
|
81
|
+
// Filter by role per public.role_app_permissions — see launcher's
|
|
82
|
+
// existing route for the exact query shape:
|
|
83
|
+
// xzibit-apps/launcher/src/app/api/me/apps/route.ts
|
|
84
|
+
|
|
85
|
+
if (error) {
|
|
86
|
+
console.error('[GET /api/me/apps] query failed:', error);
|
|
87
|
+
return NextResponse.json({ error: 'Server error' }, { status: 500 });
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return NextResponse.json({ apps: data });
|
|
91
|
+
} catch (err) {
|
|
92
|
+
console.error('[GET /api/me/apps] unexpected error:', err);
|
|
93
|
+
return NextResponse.json({ error: 'Server error' }, { status: 500 });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Individual primitives
|
|
99
|
+
|
|
100
|
+
If you need the components separately:
|
|
101
|
+
|
|
102
|
+
```tsx
|
|
103
|
+
import { BackToLauncher, AppsDropdown, XzibitMark, useApps } from '@xzibit/ui';
|
|
104
|
+
|
|
105
|
+
// Just the back-to-launcher anchor
|
|
106
|
+
<BackToLauncher />
|
|
107
|
+
|
|
108
|
+
// Just the apps dropdown (with custom endpoint)
|
|
109
|
+
<AppsDropdown endpoint="/api/custom/apps" />
|
|
110
|
+
|
|
111
|
+
// The X mark on its own
|
|
112
|
+
<XzibitMark size={32} ariaLabel="Xzibit" />
|
|
113
|
+
|
|
114
|
+
// The data hook for custom UI
|
|
115
|
+
const { apps, loading, error, refetch } = useApps();
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Theming
|
|
121
|
+
|
|
122
|
+
Components reference CSS variables for colors. Fallbacks render correct values out of the box, but the recommended way is to install `@xzibit/tokens` and import its CSS:
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
import '@xzibit/tokens/tokens.css';
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
This sets `--xz-charcoal`, `--xz-teal`, `--xz-white`, `--border`, etc. — and `@xzibit/ui` picks them up automatically.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## What's included
|
|
133
|
+
|
|
134
|
+
| Export | Purpose |
|
|
135
|
+
|---|---|
|
|
136
|
+
| `<TopBar appName="..." ... />` | Universal 44px fixed top bar (composes all the rest) |
|
|
137
|
+
| `<BackToLauncher />` | Chevron + X logo + "Xzibit Apps" anchor — single click target back to launcher |
|
|
138
|
+
| `<AppsDropdown />` | Sectioned + alphabetical apps dropdown driven by `/api/me/apps` |
|
|
139
|
+
| `<XzibitMark size={28} />` | Xzibit X brand mark as inline SVG (any size, any density) |
|
|
140
|
+
| `useApps()` | React hook fetching `/api/me/apps` with loading + error + refetch |
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## What's NOT included (yet)
|
|
145
|
+
|
|
146
|
+
- **Modal wrapper** — coming v0.2, wraps `@radix-ui/react-dialog`. For now, install Radix Dialog directly and follow DESIGN-STANDARD.md §Modal / Dialog
|
|
147
|
+
- **Toast wrapper** — coming v0.2, wraps `sonner`. For now, install Sonner directly and follow DESIGN-STANDARD.md §Toast / Notification
|
|
148
|
+
- **Form primitives** — apps maintain their own per DESIGN-STANDARD.md §Form Patterns
|
|
149
|
+
- **App-specific components** — Card, Button, FormInput, etc. live in each app
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Versioning
|
|
154
|
+
|
|
155
|
+
Semantic versioning. Apps consume specific versions per CODING-STANDARDS §21.2 (pin production-critical deps; no `^` ranges).
|
|
156
|
+
|
|
157
|
+
- **Patch** (0.1.x): bug fixes; no API changes
|
|
158
|
+
- **Minor** (0.x.0): new components / props (no breaking changes)
|
|
159
|
+
- **Major** (x.0.0): breaking changes to existing component APIs (cycle through deprecation per CHANGELOG)
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Authority
|
|
164
|
+
|
|
165
|
+
When `_portfolio/CONVENTIONS/DESIGN-STANDARD.md` changes, this package bumps to match within ~1 week. The reverse is not true — never change a component here without amending the standard first.
|
|
166
|
+
|
|
167
|
+
Sister-request the Xzibit Apps Design Standards Cowork for amendments to DESIGN-STANDARD or new components requested for `@xzibit/ui`.
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## License
|
|
172
|
+
|
|
173
|
+
MIT. See [LICENSE](./LICENSE).
|