@roxyapi/ui 0.2.3 → 0.3.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.
Files changed (119) hide show
  1. package/AGENTS.md +15 -10
  2. package/README.md +15 -10
  3. package/dist/cdn/components/compatibility-card.js.map +1 -1
  4. package/dist/cdn/components/dasha-timeline.js +8 -8
  5. package/dist/cdn/components/dasha-timeline.js.map +2 -2
  6. package/dist/cdn/components/divisional-chart.js +35 -23
  7. package/dist/cdn/components/divisional-chart.js.map +4 -4
  8. package/dist/cdn/components/guna-milan.js.map +1 -1
  9. package/dist/cdn/components/kp-chart.js +306 -0
  10. package/dist/cdn/components/kp-chart.js.map +7 -0
  11. package/dist/cdn/components/kp-planets-table.js.map +1 -1
  12. package/dist/cdn/components/kp-ruling-planets.js +269 -0
  13. package/dist/cdn/components/kp-ruling-planets.js.map +7 -0
  14. package/dist/cdn/components/location-search.js +7 -5
  15. package/dist/cdn/components/location-search.js.map +3 -3
  16. package/dist/cdn/components/moon-phase.js.map +1 -1
  17. package/dist/cdn/components/nakshatra-card.js +229 -0
  18. package/dist/cdn/components/nakshatra-card.js.map +7 -0
  19. package/dist/cdn/components/natal-chart.js +228 -115
  20. package/dist/cdn/components/natal-chart.js.map +4 -4
  21. package/dist/cdn/components/numerology-card.js +3 -3
  22. package/dist/cdn/components/numerology-card.js.map +2 -2
  23. package/dist/cdn/components/panchang-table.js.map +1 -1
  24. package/dist/cdn/components/shadbala-table.js.map +1 -1
  25. package/dist/cdn/components/synastry-chart.js +3 -3
  26. package/dist/cdn/components/synastry-chart.js.map +2 -2
  27. package/dist/cdn/components/transits-table.js.map +1 -1
  28. package/dist/cdn/components/vedic-kundli.js +34 -22
  29. package/dist/cdn/components/vedic-kundli.js.map +4 -4
  30. package/dist/cdn/components/vedic-planets-table.js +231 -0
  31. package/dist/cdn/components/vedic-planets-table.js.map +7 -0
  32. package/dist/cdn/components/western-planets-table.js +220 -0
  33. package/dist/cdn/components/western-planets-table.js.map +7 -0
  34. package/dist/cdn/roxy-ui.js +1078 -331
  35. package/dist/cdn/roxy-ui.js.map +4 -4
  36. package/dist/components/compatibility-card.js.map +1 -1
  37. package/dist/components/dasha-timeline.d.ts.map +1 -1
  38. package/dist/components/dasha-timeline.js.map +2 -2
  39. package/dist/components/divisional-chart.d.ts +5 -3
  40. package/dist/components/divisional-chart.d.ts.map +1 -1
  41. package/dist/components/divisional-chart.js +159 -38
  42. package/dist/components/divisional-chart.js.map +3 -3
  43. package/dist/components/guna-milan.js.map +1 -1
  44. package/dist/components/kp-chart.d.ts +26 -0
  45. package/dist/components/kp-chart.d.ts.map +1 -0
  46. package/dist/components/kp-chart.js +382 -0
  47. package/dist/components/kp-chart.js.map +7 -0
  48. package/dist/components/kp-planets-table.js.map +1 -1
  49. package/dist/components/kp-ruling-planets.d.ts +20 -0
  50. package/dist/components/kp-ruling-planets.d.ts.map +1 -0
  51. package/dist/components/kp-ruling-planets.js +275 -0
  52. package/dist/components/kp-ruling-planets.js.map +7 -0
  53. package/dist/components/location-search.d.ts.map +1 -1
  54. package/dist/components/location-search.js +9 -2
  55. package/dist/components/location-search.js.map +2 -2
  56. package/dist/components/moon-phase.js.map +1 -1
  57. package/dist/components/nakshatra-card.d.ts +18 -0
  58. package/dist/components/nakshatra-card.d.ts.map +1 -0
  59. package/dist/components/nakshatra-card.js +231 -0
  60. package/dist/components/nakshatra-card.js.map +7 -0
  61. package/dist/components/natal-chart.d.ts +28 -0
  62. package/dist/components/natal-chart.d.ts.map +1 -1
  63. package/dist/components/natal-chart.js +401 -104
  64. package/dist/components/natal-chart.js.map +2 -2
  65. package/dist/components/numerology-card.d.ts.map +1 -1
  66. package/dist/components/numerology-card.js.map +2 -2
  67. package/dist/components/panchang-table.js.map +1 -1
  68. package/dist/components/shadbala-table.js.map +1 -1
  69. package/dist/components/synastry-chart.js.map +2 -2
  70. package/dist/components/transits-table.js.map +1 -1
  71. package/dist/components/vedic-kundli.d.ts +7 -3
  72. package/dist/components/vedic-kundli.d.ts.map +1 -1
  73. package/dist/components/vedic-kundli.js +209 -87
  74. package/dist/components/vedic-kundli.js.map +3 -3
  75. package/dist/components/vedic-planets-table.d.ts +21 -0
  76. package/dist/components/vedic-planets-table.d.ts.map +1 -0
  77. package/dist/components/vedic-planets-table.js +355 -0
  78. package/dist/components/vedic-planets-table.js.map +7 -0
  79. package/dist/components/western-planets-table.d.ts +21 -0
  80. package/dist/components/western-planets-table.d.ts.map +1 -0
  81. package/dist/components/western-planets-table.js +350 -0
  82. package/dist/components/western-planets-table.js.map +7 -0
  83. package/dist/index.cjs +2042 -695
  84. package/dist/index.cjs.map +4 -4
  85. package/dist/index.d.ts +5 -0
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js +2029 -682
  88. package/dist/index.js.map +4 -4
  89. package/dist/manifest.d.ts.map +1 -1
  90. package/dist/manifest.json +23 -18
  91. package/dist/styles/tokens.css +4 -0
  92. package/dist/types/types.gen.d.ts +343 -49
  93. package/dist/types/types.gen.d.ts.map +1 -1
  94. package/dist/utils/degree.d.ts +12 -0
  95. package/dist/utils/degree.d.ts.map +1 -1
  96. package/dist/utils/format.d.ts +1 -1
  97. package/dist/utils/kundli-render.d.ts +85 -12
  98. package/dist/utils/kundli-render.d.ts.map +1 -1
  99. package/dist/version.d.ts +1 -1
  100. package/package.json +1 -1
  101. package/src/components/dasha-timeline.ts +1 -7
  102. package/src/components/divisional-chart.ts +27 -41
  103. package/src/components/kp-chart.ts +313 -0
  104. package/src/components/kp-ruling-planets.ts +196 -0
  105. package/src/components/location-search.ts +16 -2
  106. package/src/components/nakshatra-card.ts +149 -0
  107. package/src/components/natal-chart.ts +408 -119
  108. package/src/components/numerology-card.ts +1 -5
  109. package/src/components/vedic-kundli.ts +30 -40
  110. package/src/components/vedic-planets-table.ts +184 -0
  111. package/src/components/western-planets-table.ts +180 -0
  112. package/src/index.ts +5 -0
  113. package/src/manifest.ts +146 -84
  114. package/src/styles/tokens.css +4 -0
  115. package/src/types/types.gen.ts +343 -49
  116. package/src/utils/degree.ts +21 -0
  117. package/src/utils/format.ts +1 -1
  118. package/src/utils/kundli-render.ts +234 -29
  119. package/src/version.ts +1 -1
@@ -0,0 +1,196 @@
1
+ import { css, html, LitElement, nothing } from 'lit';
2
+ import { customElement, property } from 'lit/decorators.js';
3
+ import type { KpRulingPlanetsResponse } from '../types/index.js';
4
+ import { baseStyles } from '../utils/base-styles.js';
5
+
6
+ /**
7
+ * KP ruling planets card. Renders /vedic-astrology/kp/ruling-planets: the day
8
+ * lord, the Moon and Lagna stellar hierarchies (sign lord, star lord, sub
9
+ * lord, sub-sub lord), the consolidated ruling-planet list ordered by
10
+ * strength, and, when birth data is supplied, the house significators per
11
+ * planet. The primary horary timing tool in KP astrology.
12
+ */
13
+ @customElement('roxy-kp-ruling-planets')
14
+ export class RoxyKpRulingPlanets extends LitElement {
15
+ static styles = [
16
+ baseStyles,
17
+ css`
18
+ .wrap {
19
+ border: 1px solid var(--roxy-border, #e4e4e7);
20
+ border-radius: var(--roxy-radius-md, 8px);
21
+ background: var(--roxy-bg, #fff);
22
+ padding: var(--roxy-space-md, 1rem);
23
+ display: grid;
24
+ gap: var(--roxy-space-md, 1rem);
25
+ box-shadow: var(--roxy-shadow-sm);
26
+ }
27
+ .title {
28
+ margin: 0;
29
+ font-size: var(--roxy-text-lg, 1.125rem);
30
+ font-weight: var(--roxy-weight-bold, 600);
31
+ }
32
+ .day-lord {
33
+ color: var(--roxy-muted, #71717a);
34
+ font-size: var(--roxy-text-sm, 0.875rem);
35
+ }
36
+ .day-lord strong {
37
+ color: var(--roxy-fg, #0a0a0a);
38
+ }
39
+ .groups {
40
+ display: grid;
41
+ grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
42
+ gap: var(--roxy-space-md, 1rem);
43
+ }
44
+ .group h3 {
45
+ margin: 0 0 var(--roxy-space-xs, 0.25rem);
46
+ font-size: var(--roxy-text-xs, 0.75rem);
47
+ font-weight: var(--roxy-weight-bold, 600);
48
+ color: var(--roxy-muted, #71717a);
49
+ text-transform: uppercase;
50
+ letter-spacing: 0.05em;
51
+ }
52
+ .group dl {
53
+ margin: 0;
54
+ display: grid;
55
+ grid-template-columns: auto 1fr;
56
+ gap: 2px var(--roxy-space-sm, 0.5rem);
57
+ font-size: var(--roxy-text-sm, 0.875rem);
58
+ }
59
+ .group dt {
60
+ color: var(--roxy-muted, #71717a);
61
+ }
62
+ .group dd {
63
+ margin: 0;
64
+ color: var(--roxy-fg, #0a0a0a);
65
+ font-weight: var(--roxy-weight-bold, 600);
66
+ }
67
+ .rp-list {
68
+ display: flex;
69
+ flex-wrap: wrap;
70
+ gap: var(--roxy-space-xs, 0.25rem);
71
+ align-items: center;
72
+ }
73
+ .rp-label {
74
+ font-size: var(--roxy-text-xs, 0.75rem);
75
+ color: var(--roxy-muted, #71717a);
76
+ text-transform: uppercase;
77
+ letter-spacing: 0.05em;
78
+ margin-right: var(--roxy-space-xs, 0.25rem);
79
+ }
80
+ .rp {
81
+ display: inline-flex;
82
+ align-items: center;
83
+ gap: 0.3em;
84
+ font-size: var(--roxy-text-sm, 0.875rem);
85
+ font-weight: var(--roxy-weight-bold, 600);
86
+ padding: 0.15em 0.6em;
87
+ border-radius: 999px;
88
+ background: color-mix(in srgb, var(--roxy-accent, #f59e0b) 18%, transparent);
89
+ color: var(--roxy-fg, #0a0a0a);
90
+ }
91
+ .rp .rank {
92
+ font-size: var(--roxy-text-xs, 0.75rem);
93
+ color: var(--roxy-accent-fg, #b45309);
94
+ }
95
+ table {
96
+ width: 100%;
97
+ border-collapse: collapse;
98
+ font-size: var(--roxy-text-sm, 0.875rem);
99
+ }
100
+ th,
101
+ td {
102
+ padding: var(--roxy-space-xs, 0.25rem) var(--roxy-space-sm, 0.5rem);
103
+ text-align: left;
104
+ border-bottom: 1px solid var(--roxy-border, #e4e4e7);
105
+ }
106
+ th {
107
+ color: var(--roxy-muted, #71717a);
108
+ font-weight: var(--roxy-weight-bold, 600);
109
+ text-transform: uppercase;
110
+ font-size: var(--roxy-text-xs, 0.75rem);
111
+ letter-spacing: 0.04em;
112
+ }
113
+ `,
114
+ ];
115
+
116
+ @property({ attribute: false })
117
+ data: KpRulingPlanetsResponse | null = null;
118
+
119
+ render() {
120
+ if (!this.data)
121
+ return html`<div class="roxy-empty" role="status">No ruling planets data</div>`;
122
+ const d = this.data;
123
+ const significators = d.significators ?? [];
124
+
125
+ return html`<div class="wrap" aria-label="KP ruling planets">
126
+ <header>
127
+ <h2 class="title">KP ruling planets</h2>
128
+ ${
129
+ d.dayLord
130
+ ? html`<div class="day-lord">Day lord: <strong>${d.dayLord}</strong></div>`
131
+ : nothing
132
+ }
133
+ </header>
134
+
135
+ <div class="groups">
136
+ <div class="group">
137
+ <h3>Moon</h3>
138
+ <dl>
139
+ <dt>Sign lord</dt><dd>${d.moonSignLord ?? ''}</dd>
140
+ <dt>Star lord</dt><dd>${d.moonStarLord ?? ''}</dd>
141
+ <dt>Sub lord</dt><dd>${d.moonSublord ?? ''}</dd>
142
+ <dt>Sub-sub lord</dt><dd>${d.moonSubSublord ?? ''}</dd>
143
+ </dl>
144
+ </div>
145
+ <div class="group">
146
+ <h3>Lagna</h3>
147
+ <dl>
148
+ <dt>Sign lord</dt><dd>${d.lagnaSignLord ?? ''}</dd>
149
+ <dt>Star lord</dt><dd>${d.lagnaStarLord ?? ''}</dd>
150
+ <dt>Sub lord</dt><dd>${d.lagnaSublord ?? ''}</dd>
151
+ <dt>Sub-sub lord</dt><dd>${d.lagnaSubSublord ?? ''}</dd>
152
+ </dl>
153
+ </div>
154
+ </div>
155
+
156
+ ${
157
+ d.rulingPlanets?.length
158
+ ? html`<div class="rp-list" role="list" aria-label="Ruling planets by strength">
159
+ <span class="rp-label">Ruling planets</span>
160
+ ${d.rulingPlanets.map(
161
+ (p, i) =>
162
+ html`<span class="rp" role="listitem"><span class="rank">${i + 1}</span> ${p}</span>`,
163
+ )}
164
+ </div>`
165
+ : nothing
166
+ }
167
+
168
+ ${
169
+ significators.length
170
+ ? html`<table aria-label="House significators">
171
+ <thead>
172
+ <tr>
173
+ <th scope="col">Planet</th>
174
+ <th scope="col">Signifies houses</th>
175
+ </tr>
176
+ </thead>
177
+ <tbody>
178
+ ${significators.map(
179
+ (s) => html`<tr>
180
+ <td>${s.planet}</td>
181
+ <td>${(s.signifies ?? []).join(', ')}</td>
182
+ </tr>`,
183
+ )}
184
+ </tbody>
185
+ </table>`
186
+ : nothing
187
+ }
188
+ </div>`;
189
+ }
190
+ }
191
+
192
+ declare global {
193
+ interface HTMLElementTagNameMap {
194
+ 'roxy-kp-ruling-planets': RoxyKpRulingPlanets;
195
+ }
196
+ }
@@ -224,8 +224,16 @@ export class RoxyLocationSearch extends LitElement {
224
224
  const headers: Record<string, string> = {
225
225
  Accept: 'application/json',
226
226
  };
227
- if (this.apiKey) headers['X-API-Key'] = this.apiKey;
228
- if (this.publishableKey) headers['X-API-Key'] = this.publishableKey;
227
+ // publishable-key wins when both are set. Surfacing the conflict at the
228
+ // console (not as a thrown error) avoids breaking widgets that legitimately
229
+ // have a stale secret key around while migrating to publishable.
230
+ if (this.apiKey && this.publishableKey) {
231
+ console.warn(
232
+ '[roxy-location-search] both api-key and publishable-key set; using publishable-key. Remove api-key from your widget markup.',
233
+ );
234
+ }
235
+ const key = this.publishableKey ?? this.apiKey;
236
+ if (key) headers['X-API-Key'] = key;
229
237
  const res = await fetch(url, { headers, signal: controller.signal });
230
238
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
231
239
  const json = (await res.json()) as SearchCitiesResponse;
@@ -301,6 +309,11 @@ export class RoxyLocationSearch extends LitElement {
301
309
  role="combobox"
302
310
  aria-expanded=${this.isOpen ? 'true' : 'false'}
303
311
  aria-controls="roxy-location-listbox"
312
+ aria-activedescendant=${
313
+ this.isOpen && this.highlight >= 0
314
+ ? `roxy-location-option-${this.highlight}`
315
+ : ''
316
+ }
304
317
  aria-autocomplete="list"
305
318
  autocomplete="off"
306
319
  placeholder=${this.placeholder}
@@ -328,6 +341,7 @@ export class RoxyLocationSearch extends LitElement {
328
341
  type="button"
329
342
  class="option"
330
343
  role="option"
344
+ id=${`roxy-location-option-${idx}`}
331
345
  aria-selected=${this.highlight === idx ? 'true' : 'false'}
332
346
  @click=${() => this.select(city)}
333
347
  @mouseenter=${() => {
@@ -0,0 +1,149 @@
1
+ import { css, html, LitElement, nothing } from 'lit';
2
+ import { customElement, property } from 'lit/decorators.js';
3
+ import type { NakshatraResponse } from '../types/index.js';
4
+ import { baseStyles } from '../utils/base-styles.js';
5
+
6
+ /**
7
+ * Nakshatra reference card. Renders /vedic-astrology/nakshatras/{id}: the
8
+ * lunar mansion number, longitude range, ruling planet, presiding deity,
9
+ * symbol, native characteristics, and traditional remedies.
10
+ */
11
+ @customElement('roxy-nakshatra-card')
12
+ export class RoxyNakshatraCard extends LitElement {
13
+ static styles = [
14
+ baseStyles,
15
+ css`
16
+ .wrap {
17
+ border: 1px solid var(--roxy-border, #e4e4e7);
18
+ border-radius: var(--roxy-radius-md, 8px);
19
+ background: var(--roxy-bg, #fff);
20
+ padding: var(--roxy-space-md, 1rem);
21
+ display: grid;
22
+ gap: var(--roxy-space-md, 1rem);
23
+ box-shadow: var(--roxy-shadow-sm);
24
+ }
25
+ .head {
26
+ display: flex;
27
+ align-items: baseline;
28
+ gap: var(--roxy-space-sm, 0.5rem);
29
+ flex-wrap: wrap;
30
+ }
31
+ .name {
32
+ margin: 0;
33
+ font-size: var(--roxy-text-lg, 1.125rem);
34
+ font-weight: var(--roxy-weight-bold, 600);
35
+ }
36
+ .number {
37
+ color: var(--roxy-accent-fg, #b45309);
38
+ font-size: var(--roxy-text-sm, 0.875rem);
39
+ font-weight: var(--roxy-weight-bold, 600);
40
+ }
41
+ .range {
42
+ color: var(--roxy-muted, #71717a);
43
+ font-size: var(--roxy-text-sm, 0.875rem);
44
+ }
45
+ .facts {
46
+ display: grid;
47
+ grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
48
+ gap: var(--roxy-space-sm, 0.5rem);
49
+ }
50
+ .fact {
51
+ display: grid;
52
+ gap: 2px;
53
+ }
54
+ .fact dt {
55
+ color: var(--roxy-muted, #71717a);
56
+ font-size: var(--roxy-text-xs, 0.75rem);
57
+ text-transform: uppercase;
58
+ letter-spacing: 0.05em;
59
+ }
60
+ .fact dd {
61
+ margin: 0;
62
+ color: var(--roxy-fg, #0a0a0a);
63
+ font-size: var(--roxy-text-sm, 0.875rem);
64
+ }
65
+ .section h3 {
66
+ margin: 0 0 var(--roxy-space-xs, 0.25rem);
67
+ font-size: var(--roxy-text-sm, 0.875rem);
68
+ font-weight: var(--roxy-weight-bold, 600);
69
+ color: var(--roxy-muted, #71717a);
70
+ text-transform: uppercase;
71
+ letter-spacing: 0.05em;
72
+ }
73
+ .section p {
74
+ margin: 0;
75
+ font-size: var(--roxy-text-sm, 0.875rem);
76
+ color: var(--roxy-fg, #0a0a0a);
77
+ line-height: 1.5;
78
+ }
79
+ .remedies {
80
+ display: grid;
81
+ gap: var(--roxy-space-xs, 0.25rem);
82
+ }
83
+ .remedy {
84
+ font-size: var(--roxy-text-sm, 0.875rem);
85
+ color: var(--roxy-fg, #0a0a0a);
86
+ }
87
+ .remedy strong {
88
+ color: var(--roxy-muted, #71717a);
89
+ font-weight: var(--roxy-weight-bold, 600);
90
+ }
91
+ `,
92
+ ];
93
+
94
+ @property({ attribute: false })
95
+ data: NakshatraResponse | null = null;
96
+
97
+ render() {
98
+ if (!this.data)
99
+ return html`<div class="roxy-empty" role="status">No nakshatra data</div>`;
100
+ const n = this.data;
101
+ const remedies = n.remedies;
102
+
103
+ return html`<article class="wrap" aria-label=${`Nakshatra ${n.name}`}>
104
+ <header class="head">
105
+ <h2 class="name">${n.name}</h2>
106
+ ${
107
+ typeof n.number === 'number'
108
+ ? html`<span class="number">Nakshatra ${n.number} of 27</span>`
109
+ : nothing
110
+ }
111
+ ${n.range ? html`<span class="range">${n.range}</span>` : nothing}
112
+ </header>
113
+
114
+ <dl class="facts">
115
+ ${n.lord ? html`<div class="fact"><dt>Lord</dt><dd>${n.lord}</dd></div>` : nothing}
116
+ ${n.deity ? html`<div class="fact"><dt>Deity</dt><dd>${n.deity}</dd></div>` : nothing}
117
+ ${n.symbol ? html`<div class="fact"><dt>Symbol</dt><dd>${n.symbol}</dd></div>` : nothing}
118
+ </dl>
119
+
120
+ ${
121
+ n.characteristics
122
+ ? html`<div class="section">
123
+ <h3>Characteristics</h3>
124
+ <p>${n.characteristics}</p>
125
+ </div>`
126
+ : nothing
127
+ }
128
+
129
+ ${
130
+ remedies
131
+ ? html`<div class="section">
132
+ <h3>Remedies</h3>
133
+ <div class="remedies">
134
+ ${remedies.mantras ? html`<div class="remedy"><strong>Mantras:</strong> ${remedies.mantras}</div>` : nothing}
135
+ ${remedies.gemstones ? html`<div class="remedy"><strong>Gemstones:</strong> ${remedies.gemstones}</div>` : nothing}
136
+ ${remedies.rituals ? html`<div class="remedy"><strong>Rituals:</strong> ${remedies.rituals}</div>` : nothing}
137
+ </div>
138
+ </div>`
139
+ : nothing
140
+ }
141
+ </article>`;
142
+ }
143
+ }
144
+
145
+ declare global {
146
+ interface HTMLElementTagNameMap {
147
+ 'roxy-nakshatra-card': RoxyNakshatraCard;
148
+ }
149
+ }