@roxyapi/ui 0.8.0 → 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 +49 -47
- package/README.md +74 -47
- 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
|
@@ -122,16 +122,15 @@ Every chart endpoint accepts `timezone` as either a decimal-hour offset (`5.5` f
|
|
|
122
122
|
|
|
123
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
|
-
|
|
131
|
-
// Browser (widgets auto-mount): publishable key
|
|
132
|
-
<div data-roxy-widget="natal-chart" data-publishable-key="pk_live_xxx" ...></div>
|
|
133
130
|
```
|
|
134
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
|
+
|
|
135
134
|
### 5. Missing `'use client'` in Next.js App Router
|
|
136
135
|
|
|
137
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.
|
|
@@ -194,30 +193,30 @@ import type { NatalChartResponse } from '@roxyapi/sdk';
|
|
|
194
193
|
|
|
195
194
|
### Pattern 1: vanilla HTML, no build step
|
|
196
195
|
|
|
196
|
+
Fetch on your server with the secret key, then inline the response into the component as a child `<script type="application/json" class="roxy-data">`. The component reads it on load. No key in the browser.
|
|
197
|
+
|
|
197
198
|
```html
|
|
198
199
|
<script
|
|
199
200
|
src="https://cdn.jsdelivr.net/npm/@roxyapi/ui@latest/dist/cdn/roxy-ui.js"
|
|
200
201
|
crossorigin="anonymous"
|
|
201
202
|
></script>
|
|
202
203
|
|
|
203
|
-
<roxy-natal-chart
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
const { data } = await roxy.astrology.generateNatalChart({
|
|
209
|
-
body: { date: '1990-01-15', time: '14:30:00', latitude: 19.07, longitude: 72.88, timezone: 5.5 },
|
|
210
|
-
});
|
|
211
|
-
document.getElementById('chart').data = data;
|
|
212
|
-
</script>
|
|
204
|
+
<roxy-natal-chart>
|
|
205
|
+
<script type="application/json" class="roxy-data">
|
|
206
|
+
{ "planets": [ ... ], "houses": [ ... ], "aspects": [ ... ] }
|
|
207
|
+
</script>
|
|
208
|
+
</roxy-natal-chart>
|
|
213
209
|
```
|
|
214
210
|
|
|
215
|
-
|
|
211
|
+
Setting the JavaScript `data` property always wins over the inlined JSON, so the same element also drives dynamic pages.
|
|
212
|
+
|
|
213
|
+
### Pattern 2: React, interactive
|
|
214
|
+
|
|
215
|
+
`<RoxyLocationSearch>` runs in the browser. On select, call your own route, which holds the secret key, and set the returned data on the chart. The key never reaches the client.
|
|
216
216
|
|
|
217
217
|
```tsx
|
|
218
218
|
'use client';
|
|
219
219
|
|
|
220
|
-
import { createRoxy } from '@roxyapi/sdk';
|
|
221
220
|
import {
|
|
222
221
|
RoxyNatalChart,
|
|
223
222
|
RoxyLocationSearch,
|
|
@@ -225,18 +224,18 @@ import {
|
|
|
225
224
|
} from '@roxyapi/ui-react';
|
|
226
225
|
import { useState } from 'react';
|
|
227
226
|
|
|
228
|
-
const roxy = createRoxy(process.env.NEXT_PUBLIC_ROXY_API_KEY!);
|
|
229
|
-
|
|
230
227
|
export function BirthChartView() {
|
|
231
228
|
const [chart, setChart] = useState<RoxyNatalChartProps['data']>(undefined);
|
|
232
229
|
|
|
233
230
|
const onLocationSelect = async (e: CustomEvent<{ latitude?: number; longitude?: number; timezone?: number | string }>) => {
|
|
234
231
|
const { latitude, longitude, timezone } = e.detail;
|
|
235
232
|
if (latitude == null || longitude == null) return;
|
|
236
|
-
|
|
237
|
-
|
|
233
|
+
// Your route calls roxy.astrology.generateNatalChart with the secret key.
|
|
234
|
+
const res = await fetch('/api/natal-chart', {
|
|
235
|
+
method: 'POST',
|
|
236
|
+
body: JSON.stringify({ date: '1990-01-15', time: '14:30:00', latitude, longitude, timezone }),
|
|
238
237
|
});
|
|
239
|
-
setChart(
|
|
238
|
+
setChart(await res.json());
|
|
240
239
|
};
|
|
241
240
|
|
|
242
241
|
return (
|
|
@@ -248,9 +247,11 @@ export function BirthChartView() {
|
|
|
248
247
|
}
|
|
249
248
|
```
|
|
250
249
|
|
|
250
|
+
For a static chart with no picker, fetch in a Server Component and pass `data` to a client component (Pattern 6).
|
|
251
|
+
|
|
251
252
|
### Pattern 3: schema-driven form
|
|
252
253
|
|
|
253
|
-
`<roxy-endpoint-form>` reads the OpenAPI spec and renders the inputs for any endpoint.
|
|
254
|
+
`<roxy-endpoint-form>` reads the OpenAPI spec and renders the inputs for any endpoint. On `roxy-submit`, POST the validated values to your own route, which calls the SDK with the secret key, then set the returned data on the target component.
|
|
254
255
|
|
|
255
256
|
```html
|
|
256
257
|
<roxy-endpoint-form
|
|
@@ -258,41 +259,42 @@ export function BirthChartView() {
|
|
|
258
259
|
method="POST"
|
|
259
260
|
submit-label="Generate kundli"
|
|
260
261
|
></roxy-endpoint-form>
|
|
262
|
+
<roxy-vedic-kundli chart-style="south"></roxy-vedic-kundli>
|
|
261
263
|
|
|
262
264
|
<script type="module">
|
|
263
|
-
import { createRoxy } from 'https://cdn.jsdelivr.net/npm/@roxyapi/sdk@latest/dist/factory.js';
|
|
264
|
-
const roxy = createRoxy('pk_live_xxx');
|
|
265
265
|
const form = document.querySelector('roxy-endpoint-form');
|
|
266
266
|
form.addEventListener('roxy-submit', async (e) => {
|
|
267
|
-
|
|
268
|
-
const
|
|
269
|
-
document.querySelector('roxy-vedic-kundli').data =
|
|
267
|
+
// Your route calls roxy.vedicAstrology.generateBirthChart with the secret key.
|
|
268
|
+
const res = await fetch('/api/kundli', { method: 'POST', body: JSON.stringify(e.detail.values) });
|
|
269
|
+
document.querySelector('roxy-vedic-kundli').data = await res.json();
|
|
270
270
|
});
|
|
271
271
|
</script>
|
|
272
272
|
```
|
|
273
273
|
|
|
274
|
-
### Pattern 4:
|
|
274
|
+
### Pattern 4: fully client-side with a publishable key (no server)
|
|
275
275
|
|
|
276
|
-
|
|
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
277
|
|
|
278
278
|
```html
|
|
279
|
-
<
|
|
280
|
-
|
|
281
|
-
defer
|
|
282
|
-
></script>
|
|
279
|
+
<roxy-location-search publishable-key="pk_live_..."></roxy-location-search>
|
|
280
|
+
<roxy-natal-chart></roxy-natal-chart>
|
|
283
281
|
|
|
284
|
-
<
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
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>
|
|
293
295
|
```
|
|
294
296
|
|
|
295
|
-
|
|
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.
|
|
296
298
|
|
|
297
299
|
### Pattern 5: MCP tool-call response
|
|
298
300
|
|
|
@@ -360,13 +362,13 @@ This is how the WordPress plugin renders: PHP fetches the response server-side,
|
|
|
360
362
|
|
|
361
363
|
## Theming and dark mode
|
|
362
364
|
|
|
363
|
-
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.
|
|
364
366
|
|
|
365
367
|
| Signal | Where | Effect |
|
|
366
368
|
|---|---|---|
|
|
367
369
|
| `prefers-color-scheme: dark` | OS | Default. Follows user system setting. |
|
|
368
370
|
| `data-theme="light"` or `data-theme="dark"` | `<html>` / `<body>` / any ancestor / the component itself | Wins over OS. Per-element override scope works. |
|
|
369
|
-
| `.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). |
|
|
370
372
|
|
|
371
373
|
To toggle at runtime:
|
|
372
374
|
|
|
@@ -396,7 +398,7 @@ Every visible aspect of the chart is driven by `--roxy-*` CSS custom properties
|
|
|
396
398
|
|
|
397
399
|
## Domain ordering
|
|
398
400
|
|
|
399
|
-
When listing domains in user-visible copy, use the canonical order: Western astrology, Vedic astrology, numerology, tarot, biorhythm, I Ching, crystals, dreams, angel numbers. Location is utility, not a selling domain.
|
|
401
|
+
When listing domains in user-visible copy, use the canonical order: Western astrology, Vedic astrology, numerology, tarot, human design, forecast, biorhythm, I Ching, crystals, dreams, angel numbers. Location is utility, not a selling domain.
|
|
400
402
|
|
|
401
403
|
## What not to ship
|
|
402
404
|
|
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
|
|
|
@@ -221,42 +221,24 @@ Tables, cards, forms, and helper components in the [live demo](https://roxyapi.g
|
|
|
221
221
|
|
|
222
222
|
## Start with one component
|
|
223
223
|
|
|
224
|
-
|
|
224
|
+
Fetch with the typed SDK, pass `data` to the component. No glue code.
|
|
225
225
|
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
crossorigin="anonymous"
|
|
230
|
-
defer
|
|
231
|
-
></script>
|
|
232
|
-
<roxy-natal-chart id="chart"></roxy-natal-chart>
|
|
233
|
-
<script type="module">
|
|
234
|
-
import { createRoxy } from 'https://cdn.jsdelivr.net/npm/@roxyapi/sdk@latest/dist/factory.js';
|
|
235
|
-
const roxy = createRoxy('YOUR_API_KEY');
|
|
236
|
-
const { data } = await roxy.astrology.generateNatalChart({
|
|
237
|
-
body: { date: '1990-01-15', time: '14:30:00', latitude: 19.07, longitude: 72.88, timezone: 5.5 },
|
|
238
|
-
});
|
|
239
|
-
document.getElementById('chart').data = data;
|
|
240
|
-
</script>
|
|
241
|
-
```
|
|
226
|
+
```tsx
|
|
227
|
+
import { createRoxy } from '@roxyapi/sdk';
|
|
228
|
+
import { RoxyHoroscopeCard } from '@roxyapi/ui-react';
|
|
242
229
|
|
|
243
|
-
|
|
230
|
+
const roxy = createRoxy(process.env.ROXY_API_KEY!);
|
|
244
231
|
|
|
245
|
-
|
|
232
|
+
const { data } = await roxy.astrology.getDailyHoroscope({ path: { sign: 'aries' } });
|
|
246
233
|
|
|
247
|
-
|
|
248
|
-
<roxy-vedic-kundli id="kundli" chart-style="south"></roxy-vedic-kundli>
|
|
249
|
-
<script type="module">
|
|
250
|
-
import { createRoxy } from 'https://cdn.jsdelivr.net/npm/@roxyapi/sdk@latest/dist/factory.js';
|
|
251
|
-
const roxy = createRoxy('YOUR_API_KEY');
|
|
252
|
-
const { data } = await roxy.vedicAstrology.generateBirthChart({
|
|
253
|
-
body: { date: '1990-01-15', time: '14:30:00', latitude: 19.07, longitude: 72.88, timezone: 5.5 },
|
|
254
|
-
});
|
|
255
|
-
document.getElementById('kundli').data = data;
|
|
256
|
-
</script>
|
|
234
|
+
return <RoxyHoroscopeCard data={data} />;
|
|
257
235
|
```
|
|
258
236
|
|
|
259
|
-
|
|
237
|
+
Then expand into natal charts, kundli, dasha, tarot, and every other domain. The SDK returns `data`, the component renders it; the same pairing holds for all 32 components.
|
|
238
|
+
|
|
239
|
+
> **Pass `data`, not the envelope.** The SDK returns `{ data, error, request, response }`. Pass `data`, or the component renders `[object Object]`. This is the most common integration bug.
|
|
240
|
+
|
|
241
|
+
The key stays on your server. Vanilla HTML or a server-rendered page fetches the same way, then [inlines the JSON into the component](#server-rendered-no-javascript-wiring): no build step, no key in the browser. Try every component in the [live demo](https://roxyapi.github.io/ui/), each with Preview, Code, and shadcn tabs and a live color customizer.
|
|
260
242
|
|
|
261
243
|
## Install
|
|
262
244
|
|
|
@@ -312,7 +294,12 @@ Always call `/location/search` first. Every chart endpoint expects latitude, lon
|
|
|
312
294
|
|
|
313
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.
|
|
314
296
|
|
|
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
|
+
|
|
315
299
|
```html
|
|
300
|
+
<!-- Once per page: defines every roxy-* element -->
|
|
301
|
+
<script src="https://cdn.jsdelivr.net/npm/@roxyapi/ui@latest/dist/cdn/roxy-ui.js" crossorigin="anonymous" defer></script>
|
|
302
|
+
|
|
316
303
|
<roxy-natal-chart>
|
|
317
304
|
<script type="application/json" class="roxy-data">
|
|
318
305
|
{ "planets": [ ... ], "houses": [ ... ], "aspects": [ ... ] }
|
|
@@ -464,7 +451,48 @@ const { data: cc } = await roxy.tarot.castCelticCross({
|
|
|
464
451
|
<RoxyTarotSpread data={cc} />
|
|
465
452
|
```
|
|
466
453
|
|
|
467
|
-
### 5.
|
|
454
|
+
### 5. Human Design (bodygraph)
|
|
455
|
+
|
|
456
|
+
The breakout 2026 self-knowledge category, computed from the same ephemeris as Western astrology plus the I Ching gate wheel and chakra-style centers. Self-discovery apps, dating and compatibility products, and AI coaching bots ship the full bodygraph first. No coordinates needed; Human Design uses the birth instant, not the observer location.
|
|
457
|
+
|
|
458
|
+
```tsx
|
|
459
|
+
import { RoxyBodygraph } from '@roxyapi/ui-react';
|
|
460
|
+
|
|
461
|
+
// Full bodygraph. The head term every Human Design app leads with ("human design chart").
|
|
462
|
+
// Type, strategy, authority, profile, the nine centers, channels, and every gate
|
|
463
|
+
// activation in one call. Pass the birth instant only, no latitude or longitude.
|
|
464
|
+
const { data: bodygraph } = await roxy.humanDesign.generateBodygraph({
|
|
465
|
+
body: { date: '1990-01-15', time: '14:30:00', timezone: 5.5 },
|
|
466
|
+
});
|
|
467
|
+
<RoxyBodygraph data={bodygraph} />
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
### 6. Forecast (transits, cross-domain timeline)
|
|
471
|
+
|
|
472
|
+
The first cross-domain, stateless forecast in the catalog: one call merges Western transits, Vedic Vimshottari dasha boundaries, and biorhythm critical days into a single significance-scored, time-ordered timeline. Forecast feeds, transit alerts, and timing tools are the buyers. Acquire on the high-volume `astrology transits` search, convert on the cross-domain timeline no competitor ships. No coordinates needed.
|
|
473
|
+
|
|
474
|
+
```tsx
|
|
475
|
+
import { RoxyForecastTimeline } from '@roxyapi/ui-react';
|
|
476
|
+
|
|
477
|
+
// Transit forecast. The demand leader. Western transit-to-natal aspects, sign
|
|
478
|
+
// ingresses, and retrograde stations over the window.
|
|
479
|
+
const { data: transits } = await roxy.forecast.forecastTransits({
|
|
480
|
+
body: { birthData: { date: '1990-01-15', time: '14:30:00', timezone: 5.5 } },
|
|
481
|
+
});
|
|
482
|
+
<RoxyForecastTimeline data={transits} />
|
|
483
|
+
|
|
484
|
+
// Cross-domain timeline. The same window merged with Vedic dasha boundaries and
|
|
485
|
+
// biorhythm critical days into one significance-scored timeline.
|
|
486
|
+
const { data: timeline } = await roxy.forecast.generateTimeline({
|
|
487
|
+
body: {
|
|
488
|
+
birthData: { date: '1990-01-15', time: '14:30:00', timezone: 5.5 },
|
|
489
|
+
domains: ['western', 'vedic', 'biorhythm'],
|
|
490
|
+
},
|
|
491
|
+
});
|
|
492
|
+
<RoxyForecastTimeline data={timeline} />
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### 7. Biorhythm (daily, forecast)
|
|
468
496
|
|
|
469
497
|
Zero competition domain. Steady search volume with the top Google result being a static calculator page. Pure land-grab for wellness, productivity, sports, and couples apps.
|
|
470
498
|
|
|
@@ -485,7 +513,7 @@ const { data: forecast } = await roxy.biorhythm.getForecast({
|
|
|
485
513
|
<RoxyBiorhythmChart data={forecast} mode="forecast" />
|
|
486
514
|
```
|
|
487
515
|
|
|
488
|
-
###
|
|
516
|
+
### 8. I Ching (cast a reading, hexagram lookup)
|
|
489
517
|
|
|
490
518
|
Meditation apps, decision-making tools, and wisdom chatbots. `i ching API` and `hexagram API` are the keywords.
|
|
491
519
|
|
|
@@ -505,12 +533,11 @@ const { data: random } = await roxy.iching.getRandomHexagram();
|
|
|
505
533
|
|
|
506
534
|
## API keys
|
|
507
535
|
|
|
508
|
-
Get
|
|
536
|
+
Get a key at <https://roxyapi.com/account>.
|
|
509
537
|
|
|
510
|
-
|
|
511
|
-
- **Publishable key** (`pk_live_*` / `pk_test_*`). Safe in browsers, locked to the origins you register on the key. Use with the widgets auto-mount script for WordPress, Shopify, static HTML, embed scenarios. The API gateway rejects requests from any origin not on the allowlist.
|
|
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.
|
|
512
539
|
|
|
513
|
-
|
|
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)).
|
|
514
541
|
|
|
515
542
|
## Distribution
|
|
516
543
|
|
|
@@ -520,7 +547,7 @@ For the SDK examples on this page, set `ROXY_API_KEY` to a secret key in your se
|
|
|
520
547
|
| npm `@roxyapi/ui-react` | `npmjs.com/package/@roxyapi/ui-react` |
|
|
521
548
|
| jsDelivr CDN (full bundle) | `cdn.jsdelivr.net/npm/@roxyapi/ui@latest/dist/cdn/roxy-ui.js` |
|
|
522
549
|
| jsDelivr CDN (per component) | `cdn.jsdelivr.net/npm/@roxyapi/ui@latest/dist/cdn/components/{name}.js` |
|
|
523
|
-
| Widgets auto-mount | `cdn.jsdelivr.net/npm/@roxyapi/ui@latest/dist/cdn/widgets.js` |
|
|
550
|
+
| Widgets auto-mount (with browser keys, coming soon) | `cdn.jsdelivr.net/npm/@roxyapi/ui@latest/dist/cdn/widgets.js` |
|
|
524
551
|
| shadcn registry | `npx shadcn@latest add https://cdn.jsdelivr.net/gh/RoxyAPI/ui@latest/registry/{name}.json` |
|
|
525
552
|
|
|
526
553
|
## Components
|
|
@@ -574,7 +601,7 @@ For the SDK examples on this page, set `ROXY_API_KEY` to a secret key in your se
|
|
|
574
601
|
|
|
575
602
|
## Theming
|
|
576
603
|
|
|
577
|
-
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.
|
|
578
605
|
|
|
579
606
|
```css
|
|
580
607
|
:root {
|
|
@@ -657,7 +684,7 @@ Persist the choice in `localStorage` from your own code; the components do not o
|
|
|
657
684
|
<details>
|
|
658
685
|
<summary><strong>How big is each component? What is the bundle cost?</strong></summary>
|
|
659
686
|
|
|
660
|
-
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.
|
|
661
688
|
</details>
|
|
662
689
|
|
|
663
690
|
<details>
|
|
@@ -770,7 +797,7 @@ Components ship in Shadow DOM for style isolation; Tailwind utilities are scoped
|
|
|
770
797
|
<details>
|
|
771
798
|
<summary><strong>What is the security model for API keys?</strong></summary>
|
|
772
799
|
|
|
773
|
-
Two key
|
|
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`.
|
|
774
801
|
|
|
775
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.
|
|
776
803
|
</details>
|
|
@@ -781,11 +808,11 @@ For CSP, allow `script-src https://cdn.jsdelivr.net` if loading the bundle from
|
|
|
781
808
|
Semver. Pre-1.0, minor bumps may include breaking changes (we will note them in the changelog). Patch bumps are always backwards-compatible. Pin a concrete version in production code:
|
|
782
809
|
|
|
783
810
|
```bash
|
|
784
|
-
npm install @roxyapi/ui@0.
|
|
811
|
+
npm install @roxyapi/ui@0.8.x
|
|
785
812
|
```
|
|
786
813
|
|
|
787
814
|
```html
|
|
788
|
-
<script src="https://cdn.jsdelivr.net/npm/@roxyapi/ui@0.
|
|
815
|
+
<script src="https://cdn.jsdelivr.net/npm/@roxyapi/ui@0.8.0/dist/cdn/roxy-ui.js"></script>
|
|
789
816
|
```
|
|
790
817
|
|
|
791
818
|
The `@latest` URL on this page is for paste-friendly marketing; production code should pin.
|
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.
|