@roxyapi/ui 0.8.1 → 0.9.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/AGENTS.md +30 -7
- package/README.md +11 -13
- package/THEMING.md +7 -5
- package/dist/cdn/roxy-ui.js +260 -37
- package/dist/cdn/roxy-ui.js.map +4 -4
- package/dist/cdn.d.ts +8 -0
- package/dist/cdn.d.ts.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +24 -24
- package/dist/styles/tokens-css.d.ts +2 -0
- package/dist/styles/tokens-css.d.ts.map +1 -0
- package/dist/styles/tokens.css +26 -11
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/types.gen.d.ts +43 -26
- package/dist/types/types.gen.d.ts.map +1 -1
- package/dist/utils/inject-tokens.d.ts +16 -0
- package/dist/utils/inject-tokens.d.ts.map +1 -0
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/cdn.ts +15 -0
- package/src/styles/tokens-css.ts +225 -0
- package/src/styles/tokens.css +26 -11
- package/src/types/index.ts +1 -1
- package/src/types/types.gen.ts +43 -26
- package/src/utils/inject-tokens.ts +27 -0
- package/src/version.ts +1 -1
package/AGENTS.md
CHANGED
|
@@ -120,15 +120,17 @@ const { data: chart } = await roxy.astrology.generateNatalChart({
|
|
|
120
120
|
|
|
121
121
|
Every chart endpoint accepts `timezone` as either a decimal-hour offset (`5.5` for IST, `-5` for EST) or an IANA name (`'Asia/Kolkata'`, `'America/New_York'`). The decimal form is what `/location/search` returns; the IANA form is correct over DST boundaries. Pick one and stay consistent in a single integration. Mixing them does not break the API but makes the bug surface area larger.
|
|
122
122
|
|
|
123
|
-
### 4.
|
|
123
|
+
### 4. Secret key in the browser
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
Secret keys (`sk_*`) grant full account access and are server side only. Call `createRoxy(process.env.ROXY_API_KEY!)` on your server (Node, Bun, Hono, Next.js route handlers, Workers, Edge functions), then send the response, not the key, to the component. Never ship a secret key in a client bundle.
|
|
126
126
|
|
|
127
127
|
```ts
|
|
128
|
-
//
|
|
128
|
+
// Secret key: server side only
|
|
129
129
|
const roxy = createRoxy(process.env.ROXY_API_KEY!);
|
|
130
130
|
```
|
|
131
131
|
|
|
132
|
+
For direct client-side calls, use a **publishable key** (`pk_live_*` / `pk_test_*`) instead. Publishable keys are browser-safe: mint one at `roxyapi.com/account`, register the origins you embed on, and the API gateway returns 403 for any other origin. See the client-side pattern below.
|
|
133
|
+
|
|
132
134
|
### 5. Missing `'use client'` in Next.js App Router
|
|
133
135
|
|
|
134
136
|
The React components in `@roxyapi/ui-react` mount Custom Elements, which need the DOM. In the App Router, files that import them must declare `'use client'` at the top. Server Components can fetch with the SDK; the client component renders.
|
|
@@ -269,9 +271,30 @@ For a static chart with no picker, fetch in a Server Component and pass `data` t
|
|
|
269
271
|
</script>
|
|
270
272
|
```
|
|
271
273
|
|
|
272
|
-
### Pattern 4:
|
|
274
|
+
### Pattern 4: fully client-side with a publishable key (no server)
|
|
275
|
+
|
|
276
|
+
When you do not want a backend at all, mint a **publishable key** (`pk_live_*`) at `roxyapi.com/account`, register the origins you embed on, and call RoxyAPI directly from the browser. The publishable key is safe to ship in client code: it is origin-restricted (any other origin gets 403) and cannot read your account. `<roxy-location-search>` accepts the key via its `publishable-key` attribute and fetches geocoding itself; for the data endpoints you make a normal browser `fetch` with the key in the `X-API-Key` header, then assign the response to the rendering component.
|
|
277
|
+
|
|
278
|
+
```html
|
|
279
|
+
<roxy-location-search publishable-key="pk_live_..."></roxy-location-search>
|
|
280
|
+
<roxy-natal-chart></roxy-natal-chart>
|
|
281
|
+
|
|
282
|
+
<script type="module">
|
|
283
|
+
const chart = document.querySelector('roxy-natal-chart');
|
|
284
|
+
document.querySelector('roxy-location-search').addEventListener('roxy-location-select', async (e) => {
|
|
285
|
+
const { latitude, longitude, timezone } = e.detail;
|
|
286
|
+
if (latitude == null || longitude == null) return;
|
|
287
|
+
const res = await fetch('https://roxyapi.com/api/v2/astrology/natal-chart', {
|
|
288
|
+
method: 'POST',
|
|
289
|
+
headers: { 'X-API-Key': 'pk_live_...', 'Content-Type': 'application/json' },
|
|
290
|
+
body: JSON.stringify({ date: '1990-01-15', time: '14:30:00', latitude, longitude, timezone }),
|
|
291
|
+
});
|
|
292
|
+
chart.data = await res.json(); // pass the unwrapped response, not an envelope
|
|
293
|
+
});
|
|
294
|
+
</script>
|
|
295
|
+
```
|
|
273
296
|
|
|
274
|
-
|
|
297
|
+
Rendering components do not fetch on their own; you set `data`. Only `<roxy-location-search>` (and `<roxy-endpoint-form>` for the spec) fetch internally. A zero-wiring `data-*` auto-mount that fetches and renders with no script is still on the roadmap.
|
|
275
298
|
|
|
276
299
|
### Pattern 5: MCP tool-call response
|
|
277
300
|
|
|
@@ -339,13 +362,13 @@ This is how the WordPress plugin renders: PHP fetches the response server-side,
|
|
|
339
362
|
|
|
340
363
|
## Theming and dark mode
|
|
341
364
|
|
|
342
|
-
Components react to three signals in priority order. No events to dispatch. No JS bridge to write.
|
|
365
|
+
Components react to three signals in priority order. No events to dispatch. No JS bridge to write. The CDN bundle (`dist/cdn/roxy-ui.js`) auto-loads the design tokens, so a single script tag yields full theming and dark mode with nothing else to add. The npm and React paths inherit the same tokens through the components; only set up `tokens.css` yourself if you import per component without the full bundle.
|
|
343
366
|
|
|
344
367
|
| Signal | Where | Effect |
|
|
345
368
|
|---|---|---|
|
|
346
369
|
| `prefers-color-scheme: dark` | OS | Default. Follows user system setting. |
|
|
347
370
|
| `data-theme="light"` or `data-theme="dark"` | `<html>` / `<body>` / any ancestor / the component itself | Wins over OS. Per-element override scope works. |
|
|
348
|
-
| `.dark` class |
|
|
371
|
+
| `.dark` class | The component itself or any ancestor (typically `<html>`) | Same effect as `data-theme="dark"`. Use when the host stack already ships a `.dark` toggle (Tailwind, shadcn). |
|
|
349
372
|
|
|
350
373
|
To toggle at runtime:
|
|
351
374
|
|
package/README.md
CHANGED
|
@@ -55,7 +55,7 @@ Light, dark, your brand. Override one CSS variable and every component updates.
|
|
|
55
55
|
```css
|
|
56
56
|
:root {
|
|
57
57
|
/* Surface */
|
|
58
|
-
--roxy-bg: #
|
|
58
|
+
--roxy-bg: #ffffff;
|
|
59
59
|
--roxy-fg: #0a0a0a;
|
|
60
60
|
--roxy-muted: #71717a;
|
|
61
61
|
--roxy-border: #e4e4e7;
|
|
@@ -66,13 +66,13 @@ Light, dark, your brand. Override one CSS variable and every component updates.
|
|
|
66
66
|
|
|
67
67
|
/* Status (each has a -fg variant for WCAG-AA text contrast) */
|
|
68
68
|
--roxy-success: #16a34a;
|
|
69
|
-
--roxy-warning: #
|
|
69
|
+
--roxy-warning: #ea580c;
|
|
70
70
|
--roxy-danger: #dc2626;
|
|
71
|
-
--roxy-info: #
|
|
71
|
+
--roxy-info: #0284c7;
|
|
72
72
|
|
|
73
73
|
/* Shape + motion */
|
|
74
|
-
--roxy-radius-md:
|
|
75
|
-
--roxy-shadow-md: 0 4px
|
|
74
|
+
--roxy-radius-md: 8px;
|
|
75
|
+
--roxy-shadow-md: 0 4px 6px -1px rgba(0,0,0,0.08), 0 2px 4px -2px rgba(0,0,0,0.06);
|
|
76
76
|
--roxy-motion-duration: 200ms; /* 0ms when prefers-reduced-motion */
|
|
77
77
|
}
|
|
78
78
|
|
|
@@ -294,7 +294,7 @@ Always call `/location/search` first. Every chart endpoint expects latitude, lon
|
|
|
294
294
|
|
|
295
295
|
Server-rendered and cached pages (WordPress, JSX SSR, static HTML) cannot always run JavaScript to set the `data` property per element. Render the response into a child `<script type="application/json" class="roxy-data">` on the server instead. The component reads it on load. No per-element script, no API key in the browser.
|
|
296
296
|
|
|
297
|
-
Load the bundle once anywhere on the page. It registers every `roxy-*` element, so every component on the page renders from that single tag.
|
|
297
|
+
Load the bundle once anywhere on the page. It registers every `roxy-*` element and loads the design tokens, so every component on the page renders themed, in light or dark, from that single tag. Nothing else to add.
|
|
298
298
|
|
|
299
299
|
```html
|
|
300
300
|
<!-- Once per page: defines every roxy-* element -->
|
|
@@ -535,11 +535,9 @@ const { data: random } = await roxy.iching.getRandomHexagram();
|
|
|
535
535
|
|
|
536
536
|
Get a key at <https://roxyapi.com/account>.
|
|
537
537
|
|
|
538
|
-
|
|
538
|
+
Two key types. **Secret keys** (`sk_*`) grant full account access: use them server side only (Node, Bun, Hono, Next.js route handlers, Workers). Never commit one, never ship one in a client bundle. **Publishable keys** (`pk_live_*` / `pk_test_*`) are browser-safe: mint one, register the origins you embed on, and any other origin gets a 403 at the gateway. Use a publishable key when you call RoxyAPI directly from the browser with no backend.
|
|
539
539
|
|
|
540
|
-
Set `ROXY_API_KEY` to your secret key in your server env for
|
|
541
|
-
|
|
542
|
-
Browser-safe keys for direct client-side embedding are on the roadmap, not yet available. Until they ship, keep the fetch on your server.
|
|
540
|
+
Set `ROXY_API_KEY` to your secret key in your server env for the server-side SDK examples on this page. For direct client-side embedding with no backend, use a publishable key (see the fully client-side pattern in [`AGENTS.md`](AGENTS.md)).
|
|
543
541
|
|
|
544
542
|
## Distribution
|
|
545
543
|
|
|
@@ -603,7 +601,7 @@ Browser-safe keys for direct client-side embedding are on the roadmap, not yet a
|
|
|
603
601
|
|
|
604
602
|
## Theming
|
|
605
603
|
|
|
606
|
-
Every component reads from `--roxy-*` CSS custom properties. Override globally on `:root` or per element. Light + dark defaults, container queries for responsive layouts at 320px and up. See [THEMING.md](https://github.com/RoxyAPI/ui/blob/main/packages/ui/THEMING.md) for the full token reference.
|
|
604
|
+
Every component reads from `--roxy-*` CSS custom properties. Override globally on `:root` or per element. Light + dark defaults, container queries for responsive layouts at 320px and up. The CDN bundle auto-loads these tokens; your `:root { --roxy-* }` overrides always win over the defaults. See [THEMING.md](https://github.com/RoxyAPI/ui/blob/main/packages/ui/THEMING.md) for the full token reference.
|
|
607
605
|
|
|
608
606
|
```css
|
|
609
607
|
:root {
|
|
@@ -686,7 +684,7 @@ Persist the choice in `localStorage` from your own code; the components do not o
|
|
|
686
684
|
<details>
|
|
687
685
|
<summary><strong>How big is each component? What is the bundle cost?</strong></summary>
|
|
688
686
|
|
|
689
|
-
Per-component bundles run 6-10 KB gzipped, capped at 30 KB by CI. The full bundle (every component, helpers, base styles) stays well under the 150 KB CI cap, around
|
|
687
|
+
Per-component bundles run 6-10 KB gzipped, capped at 30 KB by CI. The full bundle (every component, helpers, base styles, and the inlined design tokens) stays well under the 150 KB CI cap, around 54 KB gzipped today. The React package loads the runtime on mount, so a route that renders one chart pays for one component, not the whole catalog. Pin a concrete version in production for byte-stable cache hits.
|
|
690
688
|
</details>
|
|
691
689
|
|
|
692
690
|
<details>
|
|
@@ -799,7 +797,7 @@ Components ship in Shadow DOM for style isolation; Tailwind utilities are scoped
|
|
|
799
797
|
<details>
|
|
800
798
|
<summary><strong>What is the security model for API keys?</strong></summary>
|
|
801
799
|
|
|
802
|
-
|
|
800
|
+
Two key types. Secret keys (`sk_*`) live server side only and grant full access, so never ship one in a client bundle: fetch on your server and pass the rendered response, not the key, to the browser. Publishable keys (`pk_live_*` / `pk_test_*`) are browser-safe for direct client-side embedding: they carry an origin allowlist, so a key leaked to any other origin returns 403 instead of working. Mint either at `roxyapi.com/account`.
|
|
803
801
|
|
|
804
802
|
For CSP, allow `script-src https://cdn.jsdelivr.net` if loading the bundle from the CDN. Subresource Integrity hashes are available via the jsDelivr SRI API for any pinned version.
|
|
805
803
|
</details>
|
package/THEMING.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Theming Roxy UI
|
|
2
2
|
|
|
3
|
-
Every Roxy UI component reads its colors, fonts, spacing, and motion from a single set of CSS custom properties
|
|
3
|
+
Every Roxy UI component reads its colors, fonts, spacing, and motion from a single set of `--roxy-*` CSS custom properties. Override them at `:root` to brand the whole library, or scope to one element to skin a single component. Custom properties inherit through the Shadow DOM boundary, so a value set on `:root` or any light-DOM ancestor reaches every component. The CDN bundle auto-loads the token defaults; your `:root` overrides always win over them.
|
|
4
4
|
|
|
5
5
|
## Token reference
|
|
6
6
|
|
|
@@ -99,18 +99,20 @@ roxy-natal-chart {
|
|
|
99
99
|
|
|
100
100
|
### Dark mode
|
|
101
101
|
|
|
102
|
-
Three opt-in mechanisms work out of the box.
|
|
102
|
+
Three opt-in mechanisms work out of the box. The CDN bundle auto-loads the tokens, so all three work from one script tag; on the npm path the full `@roxyapi/ui` import pulls the same tokens in.
|
|
103
103
|
|
|
104
104
|
```css
|
|
105
105
|
/* System preference: nothing to do */
|
|
106
106
|
|
|
107
|
-
/* data-theme on the document */
|
|
107
|
+
/* data-theme on the document, an ancestor, or the element itself */
|
|
108
108
|
:root[data-theme='dark'] { /* automatic */ }
|
|
109
109
|
|
|
110
|
-
/* Tailwind dark class on an ancestor */
|
|
111
|
-
.dark
|
|
110
|
+
/* Tailwind dark class on the document, an ancestor, or the element itself */
|
|
111
|
+
.dark { /* automatic */ }
|
|
112
112
|
```
|
|
113
113
|
|
|
114
|
+
Tokens set on the `:root` / `.dark` / `[data-theme]` light-DOM element inherit through the shadow boundary into every component, so a `.dark` class anywhere above a component themes it. Per-element scope works too: `<roxy-natal-chart data-theme="dark">` runs one chart in dark on an otherwise light page.
|
|
115
|
+
|
|
114
116
|
### Map Tailwind tokens
|
|
115
117
|
|
|
116
118
|
Tailwind users can map our tokens to theirs in five lines of `globals.css`. Pick the syntax that matches your Tailwind version.
|