@roxyapi/ui 0.2.1 → 0.2.3

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/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const ROXY_UI_VERSION = "0.2.1";
1
+ export declare const ROXY_UI_VERSION = "0.2.3";
2
2
  //# sourceMappingURL=version.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@roxyapi/ui",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "Web components for the RoxyAPI catalog. Drop-in charts, tables, cards, forms for astrology, tarot, numerology, biorhythm, I Ching, crystals, dreams, angel numbers, and more. One key, beautiful in 30 minutes.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -494,11 +494,11 @@ export class RoxyNatalChart extends LitElement {
494
494
  if (planets.length === 0) return nothing;
495
495
  return html`<section class="interpretations">
496
496
  <h3>Planet readings</h3>
497
- ${planets.map((p) => {
497
+ ${planets.map((p, idx) => {
498
498
  const interp = p.interpretation!;
499
499
  const glyph = PLANET_GLYPH[capitalize(p.name)] ?? '';
500
500
  const deg = formatNumber(p.degree ?? 0, 1);
501
- return html`<details class="interp-card">
501
+ return html`<details class="interp-card" name="natal-planet-readings" ?open=${idx === 0}>
502
502
  <summary>${glyph} ${p.name} <small>${p.sign ?? ''} ${deg}</small></summary>
503
503
  <div class="interp-body">
504
504
  ${interp.summary ? html`<p class="interp-summary">${interp.summary}</p>` : nothing}
@@ -143,47 +143,73 @@ export class RoxyTransitsTable extends LitElement {
143
143
  color: var(--roxy-muted, #71717a);
144
144
  }
145
145
 
146
- .nature-harmonious {
147
- color: var(--roxy-success-fg, #166534);
146
+ .overflow-scroll {
147
+ overflow-x: auto;
148
+ -webkit-overflow-scrolling: touch;
148
149
  }
149
150
 
150
- .nature-challenging {
151
- color: var(--roxy-danger-fg, #991b1b);
151
+ .aspect-card {
152
+ border: 1px solid var(--roxy-border, #e4e4e7);
153
+ border-radius: var(--roxy-radius-md, 8px);
154
+ padding: var(--roxy-space-sm, 0.5rem) var(--roxy-space-md, 1rem);
155
+ margin-bottom: var(--roxy-space-xs, 0.25rem);
152
156
  }
153
-
154
- .nature-neutral {
155
- color: var(--roxy-muted, #71717a);
156
- }
157
-
158
- .arrow-cell {
159
- display: inline-flex;
157
+ .aspect-card summary {
158
+ cursor: pointer;
159
+ font-weight: 500;
160
+ color: var(--roxy-fg, #0a0a0a);
161
+ display: flex;
162
+ flex-wrap: wrap;
160
163
  align-items: center;
161
- gap: 4px;
162
- white-space: nowrap;
164
+ gap: 0.5em;
163
165
  }
164
-
165
- .interp-row td {
166
- padding-top: 0;
167
- padding-bottom: var(--roxy-space-sm, 0.5rem);
168
- border-bottom: 1px solid var(--roxy-border, #e4e4e7);
169
- color: var(--roxy-secondary, #475569);
166
+ .aspect-card summary .meta {
167
+ color: var(--roxy-muted, #71717a);
168
+ font-weight: 400;
170
169
  font-size: var(--roxy-text-xs, 0.75rem);
170
+ margin-left: auto;
171
+ font-variant-numeric: tabular-nums;
172
+ }
173
+ .aspect-card .interp-body {
174
+ margin-top: var(--roxy-space-xs, 0.25rem);
175
+ color: var(--roxy-fg, #0a0a0a);
176
+ font-size: var(--roxy-text-sm, 0.875rem);
171
177
  line-height: 1.45;
172
178
  }
173
-
174
- .aspect-row td {
175
- border-bottom: none;
176
- padding-bottom: 4px;
179
+ .aspect-card .interp-body p {
180
+ margin: 0 0 var(--roxy-space-xs, 0.25rem);
177
181
  }
178
-
179
- .aspect-row.no-interp td {
180
- border-bottom: 1px solid var(--roxy-border, #e4e4e7);
181
- padding-bottom: var(--roxy-space-sm, 0.5rem);
182
+ .interp-keywords {
183
+ display: flex;
184
+ flex-wrap: wrap;
185
+ gap: 0.25rem;
186
+ margin-top: 0.5rem;
182
187
  }
183
-
184
- .overflow-scroll {
185
- overflow-x: auto;
186
- -webkit-overflow-scrolling: touch;
188
+ .interp-keywords .kw {
189
+ padding: 1px 8px;
190
+ border-radius: 9999px;
191
+ background: color-mix(in srgb, var(--roxy-accent, #f59e0b) 14%, transparent);
192
+ color: var(--roxy-accent-fg, #b45309);
193
+ font-size: var(--roxy-text-xs, 0.75rem);
194
+ }
195
+ .nature-badge {
196
+ display: inline-block;
197
+ padding: 1px 8px;
198
+ border-radius: 9999px;
199
+ font-size: var(--roxy-text-xs, 0.75rem);
200
+ font-weight: 600;
201
+ }
202
+ .nature-badge.harmonious {
203
+ background: color-mix(in srgb, var(--roxy-success, #16a34a) 12%, transparent);
204
+ color: var(--roxy-success-fg, #166534);
205
+ }
206
+ .nature-badge.challenging {
207
+ background: color-mix(in srgb, var(--roxy-danger, #dc2626) 12%, transparent);
208
+ color: var(--roxy-danger-fg, #991b1b);
209
+ }
210
+ .nature-badge.neutral {
211
+ background: color-mix(in srgb, var(--roxy-border, #e4e4e7) 60%, transparent);
212
+ color: var(--roxy-fg, #0a0a0a);
187
213
  }
188
214
  `,
189
215
  ];
@@ -228,7 +254,7 @@ export class RoxyTransitsTable extends LitElement {
228
254
  ? html`<div>
229
255
  <p class="section-label">Transit aspects</p>
230
256
  <div class="overflow-scroll">
231
- ${this.renderAspectsTable(transitAspects)}
257
+ ${this.renderAspectsList(transitAspects)}
232
258
  </div>
233
259
  </div>`
234
260
  : nothing
@@ -299,55 +325,44 @@ export class RoxyTransitsTable extends LitElement {
299
325
  </table>`;
300
326
  }
301
327
 
302
- private renderAspectsTable(
328
+ private renderAspectsList(
303
329
  aspects: NonNullable<TransitsResponse['transitAspects']>,
304
330
  ) {
305
- return html`<table class="aspects-table">
306
- <thead>
307
- <tr>
308
- <th scope="col">Transit Planet</th>
309
- <th scope="col">Natal Planet</th>
310
- <th scope="col">Type</th>
311
- <th scope="col">Orb</th>
312
- <th scope="col">Status</th>
313
- <th scope="col">Strength</th>
314
- </tr>
315
- </thead>
316
- <tbody>
317
- ${aspects.map((a) => {
318
- const tGlyph = PLANET_GLYPH[capitalize(a.transitPlanet)] ?? '';
319
- const nGlyph = PLANET_GLYPH[capitalize(a.natalPlanet)] ?? '';
320
- const natureClass = `nature-${(a.nature ?? '').toLowerCase()}`;
321
- const summary = a.interpretation?.summary ?? '';
322
- const rowClass = summary ? 'aspect-row' : 'aspect-row no-interp';
323
- return html`<tr class=${rowClass}>
324
- <td>
325
- <div class="arrow-cell">
326
- <span class="glyph" aria-hidden="true">${tGlyph}</span>
327
- ${a.transitPlanet}
328
- </div>
329
- </td>
330
- <td>
331
- <div class="arrow-cell">
332
- <span class="glyph" aria-hidden="true">${nGlyph}</span>
333
- ${a.natalPlanet}
334
- </div>
335
- </td>
336
- <td class=${natureClass}>${(a.type ?? '').toLowerCase()}</td>
337
- <td class="num">${formatNumber(a.orb, 2)}</td>
338
- <td>${a.isApplying ? 'Applying' : 'Separating'}</td>
339
- <td class="num">${formatNumber(a.strength, 1)}</td>
340
- </tr>
331
+ return html`<div role="list" aria-label="Transit aspects">
332
+ ${aspects.map((a, idx) => {
333
+ const tGlyph = PLANET_GLYPH[capitalize(a.transitPlanet)] ?? '';
334
+ const nGlyph = PLANET_GLYPH[capitalize(a.natalPlanet)] ?? '';
335
+ const nature = (a.nature ?? 'neutral').toLowerCase();
336
+ const interp = a.interpretation;
337
+ const type = (a.type ?? '').toLowerCase();
338
+ const status = a.isApplying ? 'Applying' : 'Separating';
339
+ return html`<details class="aspect-card" role="listitem" name="transit-aspects" ?open=${idx === 0}>
340
+ <summary>
341
+ <span aria-hidden="true">${tGlyph}</span>
342
+ ${a.transitPlanet}
343
+ <span class="nature-badge ${nature}">${type}</span>
344
+ <span aria-hidden="true">${nGlyph}</span>
345
+ ${a.natalPlanet}
346
+ <span class="meta">
347
+ ${status} · orb ${formatNumber(a.orb, 2)}° · strength ${formatNumber(a.strength, 1)}
348
+ </span>
349
+ </summary>
350
+ <div class="interp-body">
351
+ ${interp?.summary ? html`<p>${interp.summary}</p>` : nothing}
352
+ ${interp?.impact ? html`<p><strong>Impact:</strong> ${interp.impact}</p>` : nothing}
353
+ ${interp?.timing ? html`<p><strong>Timing:</strong> ${interp.timing}</p>` : nothing}
354
+ ${interp?.guidance ? html`<p><strong>Guidance:</strong> ${interp.guidance}</p>` : nothing}
341
355
  ${
342
- summary
343
- ? html`<tr class="interp-row">
344
- <td colspan="6">${summary}</td>
345
- </tr>`
356
+ interp?.keywords?.length
357
+ ? html`<div class="interp-keywords">
358
+ ${interp.keywords.map((k) => html`<span class="kw">${k}</span>`)}
359
+ </div>`
346
360
  : nothing
347
- }`;
348
- })}
349
- </tbody>
350
- </table>`;
361
+ }
362
+ </div>
363
+ </details>`;
364
+ })}
365
+ </div>`;
351
366
  }
352
367
  }
353
368
 
@@ -2,7 +2,6 @@ import { css, html, LitElement, nothing } from 'lit';
2
2
  import { customElement, property, state } from 'lit/decorators.js';
3
3
  import type { GetYogaResponse, ListYogasResponse } from '../types/index.js';
4
4
  import { baseStyles } from '../utils/base-styles.js';
5
- import { debounce } from '../utils/debounce.js';
6
5
 
7
6
  type YogaListData =
8
7
  | ListYogasResponse
@@ -178,9 +177,9 @@ export class RoxyYogaList extends LitElement {
178
177
  @state()
179
178
  private filter = '';
180
179
 
181
- private readonly handleInput = debounce((e: Event) => {
180
+ private readonly handleInput = (e: Event) => {
182
181
  this.filter = (e.target as HTMLInputElement).value;
183
- }, 200);
182
+ };
184
183
 
185
184
  private renderQualityChip(quality: string) {
186
185
  const cls = `quality-chip quality-${quality}`;
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  // Generated by scripts/sync-version.ts. Do not edit.
2
- export const ROXY_UI_VERSION = '0.2.1';
2
+ export const ROXY_UI_VERSION = '0.2.3';