@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.
- package/AGENTS.md +15 -10
- package/README.md +15 -10
- package/dist/cdn/components/compatibility-card.js.map +1 -1
- package/dist/cdn/components/dasha-timeline.js +8 -8
- package/dist/cdn/components/dasha-timeline.js.map +2 -2
- package/dist/cdn/components/divisional-chart.js +35 -23
- package/dist/cdn/components/divisional-chart.js.map +4 -4
- package/dist/cdn/components/guna-milan.js.map +1 -1
- package/dist/cdn/components/kp-chart.js +306 -0
- package/dist/cdn/components/kp-chart.js.map +7 -0
- package/dist/cdn/components/kp-planets-table.js.map +1 -1
- package/dist/cdn/components/kp-ruling-planets.js +269 -0
- package/dist/cdn/components/kp-ruling-planets.js.map +7 -0
- package/dist/cdn/components/location-search.js +7 -5
- package/dist/cdn/components/location-search.js.map +3 -3
- package/dist/cdn/components/moon-phase.js.map +1 -1
- package/dist/cdn/components/nakshatra-card.js +229 -0
- package/dist/cdn/components/nakshatra-card.js.map +7 -0
- package/dist/cdn/components/natal-chart.js +228 -115
- package/dist/cdn/components/natal-chart.js.map +4 -4
- package/dist/cdn/components/numerology-card.js +3 -3
- package/dist/cdn/components/numerology-card.js.map +2 -2
- package/dist/cdn/components/panchang-table.js.map +1 -1
- package/dist/cdn/components/shadbala-table.js.map +1 -1
- package/dist/cdn/components/synastry-chart.js +3 -3
- package/dist/cdn/components/synastry-chart.js.map +2 -2
- package/dist/cdn/components/transits-table.js.map +1 -1
- package/dist/cdn/components/vedic-kundli.js +34 -22
- package/dist/cdn/components/vedic-kundli.js.map +4 -4
- package/dist/cdn/components/vedic-planets-table.js +231 -0
- package/dist/cdn/components/vedic-planets-table.js.map +7 -0
- package/dist/cdn/components/western-planets-table.js +220 -0
- package/dist/cdn/components/western-planets-table.js.map +7 -0
- package/dist/cdn/roxy-ui.js +1078 -331
- package/dist/cdn/roxy-ui.js.map +4 -4
- package/dist/components/compatibility-card.js.map +1 -1
- package/dist/components/dasha-timeline.d.ts.map +1 -1
- package/dist/components/dasha-timeline.js.map +2 -2
- package/dist/components/divisional-chart.d.ts +5 -3
- package/dist/components/divisional-chart.d.ts.map +1 -1
- package/dist/components/divisional-chart.js +159 -38
- package/dist/components/divisional-chart.js.map +3 -3
- package/dist/components/guna-milan.js.map +1 -1
- package/dist/components/kp-chart.d.ts +26 -0
- package/dist/components/kp-chart.d.ts.map +1 -0
- package/dist/components/kp-chart.js +382 -0
- package/dist/components/kp-chart.js.map +7 -0
- package/dist/components/kp-planets-table.js.map +1 -1
- package/dist/components/kp-ruling-planets.d.ts +20 -0
- package/dist/components/kp-ruling-planets.d.ts.map +1 -0
- package/dist/components/kp-ruling-planets.js +275 -0
- package/dist/components/kp-ruling-planets.js.map +7 -0
- package/dist/components/location-search.d.ts.map +1 -1
- package/dist/components/location-search.js +9 -2
- package/dist/components/location-search.js.map +2 -2
- package/dist/components/moon-phase.js.map +1 -1
- package/dist/components/nakshatra-card.d.ts +18 -0
- package/dist/components/nakshatra-card.d.ts.map +1 -0
- package/dist/components/nakshatra-card.js +231 -0
- package/dist/components/nakshatra-card.js.map +7 -0
- package/dist/components/natal-chart.d.ts +28 -0
- package/dist/components/natal-chart.d.ts.map +1 -1
- package/dist/components/natal-chart.js +401 -104
- package/dist/components/natal-chart.js.map +2 -2
- package/dist/components/numerology-card.d.ts.map +1 -1
- package/dist/components/numerology-card.js.map +2 -2
- package/dist/components/panchang-table.js.map +1 -1
- package/dist/components/shadbala-table.js.map +1 -1
- package/dist/components/synastry-chart.js.map +2 -2
- package/dist/components/transits-table.js.map +1 -1
- package/dist/components/vedic-kundli.d.ts +7 -3
- package/dist/components/vedic-kundli.d.ts.map +1 -1
- package/dist/components/vedic-kundli.js +209 -87
- package/dist/components/vedic-kundli.js.map +3 -3
- package/dist/components/vedic-planets-table.d.ts +21 -0
- package/dist/components/vedic-planets-table.d.ts.map +1 -0
- package/dist/components/vedic-planets-table.js +355 -0
- package/dist/components/vedic-planets-table.js.map +7 -0
- package/dist/components/western-planets-table.d.ts +21 -0
- package/dist/components/western-planets-table.d.ts.map +1 -0
- package/dist/components/western-planets-table.js +350 -0
- package/dist/components/western-planets-table.js.map +7 -0
- package/dist/index.cjs +2042 -695
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2029 -682
- package/dist/index.js.map +4 -4
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.json +23 -18
- package/dist/styles/tokens.css +4 -0
- package/dist/types/types.gen.d.ts +343 -49
- package/dist/types/types.gen.d.ts.map +1 -1
- package/dist/utils/degree.d.ts +12 -0
- package/dist/utils/degree.d.ts.map +1 -1
- package/dist/utils/format.d.ts +1 -1
- package/dist/utils/kundli-render.d.ts +85 -12
- package/dist/utils/kundli-render.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/components/dasha-timeline.ts +1 -7
- package/src/components/divisional-chart.ts +27 -41
- package/src/components/kp-chart.ts +313 -0
- package/src/components/kp-ruling-planets.ts +196 -0
- package/src/components/location-search.ts +16 -2
- package/src/components/nakshatra-card.ts +149 -0
- package/src/components/natal-chart.ts +408 -119
- package/src/components/numerology-card.ts +1 -5
- package/src/components/vedic-kundli.ts +30 -40
- package/src/components/vedic-planets-table.ts +184 -0
- package/src/components/western-planets-table.ts +180 -0
- package/src/index.ts +5 -0
- package/src/manifest.ts +146 -84
- package/src/styles/tokens.css +4 -0
- package/src/types/types.gen.ts +343 -49
- package/src/utils/degree.ts +21 -0
- package/src/utils/format.ts +1 -1
- package/src/utils/kundli-render.ts +234 -29
- package/src/version.ts +1 -1
|
@@ -1,27 +1,25 @@
|
|
|
1
1
|
import { css, html, LitElement } from 'lit';
|
|
2
2
|
import { customElement, property } from 'lit/decorators.js';
|
|
3
|
-
import { RASHI_KEYS } from '../tokens/index.js';
|
|
4
3
|
import type { BirthChartResponse } from '../types/index.js';
|
|
5
4
|
import { baseStyles } from '../utils/base-styles.js';
|
|
6
|
-
import type { HouseDef } from '../utils/kundli-render.js';
|
|
7
5
|
import {
|
|
8
|
-
|
|
6
|
+
buildHousesFromMeta,
|
|
7
|
+
type HouseDef,
|
|
8
|
+
renderEastFrame,
|
|
9
|
+
renderEastHouseGroup,
|
|
9
10
|
renderNorthFrame,
|
|
10
11
|
renderNorthHouseGroup,
|
|
11
12
|
renderSouthFrame,
|
|
12
13
|
renderSouthHouseGroup,
|
|
13
14
|
} from '../utils/kundli-render.js';
|
|
14
15
|
|
|
15
|
-
type RashiBucket = BirthChartResponse['aries'];
|
|
16
|
-
|
|
17
|
-
// The /vedic-astrology/birth-chart response carries all 12 rashi keys
|
|
18
|
-
// (aries, taurus, ..., pisces), each shaped like the spec-typed `aries`
|
|
19
|
-
// bucket. This local alias indexes by rashi name without per-call casts.
|
|
20
|
-
type BirthChartByRashi = BirthChartResponse & Record<string, RashiBucket>;
|
|
21
|
-
|
|
22
16
|
/**
|
|
23
|
-
* Vedic kundli (D1 Rashi chart).
|
|
24
|
-
*
|
|
17
|
+
* Vedic kundli (D1 Rashi chart). Pass `data` from /vedic-astrology/birth-chart.
|
|
18
|
+
* Three render styles via the `chart-style` attribute: south (default),
|
|
19
|
+
* north, and east. All three draw the identical planet-in-sign data, so the
|
|
20
|
+
* style is purely a layout choice. Each planet shows its abbreviation and
|
|
21
|
+
* whole-degree, with an SVG tooltip carrying exact position, nakshatra, pada,
|
|
22
|
+
* and avastha.
|
|
25
23
|
*
|
|
26
24
|
* Theming flows through CSS custom properties on :host, so the chart adopts
|
|
27
25
|
* the host page palette without runtime color probing.
|
|
@@ -58,7 +56,7 @@ export class RoxyVedicKundli extends LitElement {
|
|
|
58
56
|
}
|
|
59
57
|
.planet-text {
|
|
60
58
|
fill: var(--roxy-fg, #0a0a0a);
|
|
61
|
-
font-size:
|
|
59
|
+
font-size: 10px;
|
|
62
60
|
font-weight: 600;
|
|
63
61
|
font-family: var(--roxy-font-sans);
|
|
64
62
|
}
|
|
@@ -87,35 +85,31 @@ export class RoxyVedicKundli extends LitElement {
|
|
|
87
85
|
data: BirthChartResponse | null = null;
|
|
88
86
|
|
|
89
87
|
@property({ type: String, reflect: true, attribute: 'chart-style' })
|
|
90
|
-
chartStyle: 'south' | 'north' = 'south';
|
|
88
|
+
chartStyle: 'south' | 'north' | 'east' = 'south';
|
|
91
89
|
|
|
92
90
|
private buildHouses(): HouseDef[] {
|
|
93
|
-
if (!this.data) return [];
|
|
94
|
-
|
|
95
|
-
const lagnaSign = this.data?.meta?.Lagna?.rashi ?? '';
|
|
96
|
-
const houses: HouseDef[] = [];
|
|
97
|
-
for (let i = 0; i < 12; i++) {
|
|
98
|
-
const key = RASHI_KEYS[i];
|
|
99
|
-
const bucket = data[key];
|
|
100
|
-
const planets = (bucket?.signs ?? []).map((p) => p.graha).filter(Boolean);
|
|
101
|
-
const sign = RASHI_TO_SIGN[key] ?? '';
|
|
102
|
-
houses.push({
|
|
103
|
-
number: i + 1,
|
|
104
|
-
sign,
|
|
105
|
-
planets,
|
|
106
|
-
isLagna: lagnaSign
|
|
107
|
-
? lagnaSign.toLowerCase() === sign.toLowerCase()
|
|
108
|
-
: false,
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
return houses;
|
|
91
|
+
if (!this.data?.meta) return [];
|
|
92
|
+
return buildHousesFromMeta(this.data.meta);
|
|
112
93
|
}
|
|
113
94
|
|
|
114
95
|
render() {
|
|
115
96
|
if (!this.data)
|
|
116
97
|
return html`<div class="roxy-empty" role="status">No kundli data</div>`;
|
|
117
98
|
const houses = this.buildHouses();
|
|
118
|
-
const
|
|
99
|
+
const style = this.chartStyle;
|
|
100
|
+
|
|
101
|
+
const frame =
|
|
102
|
+
style === 'north'
|
|
103
|
+
? renderNorthFrame()
|
|
104
|
+
: style === 'east'
|
|
105
|
+
? renderEastFrame()
|
|
106
|
+
: renderSouthFrame();
|
|
107
|
+
const houseGroup =
|
|
108
|
+
style === 'north'
|
|
109
|
+
? renderNorthHouseGroup
|
|
110
|
+
: style === 'east'
|
|
111
|
+
? renderEastHouseGroup
|
|
112
|
+
: renderSouthHouseGroup;
|
|
119
113
|
|
|
120
114
|
return html`<div class="wrap">
|
|
121
115
|
<h2 class="title">Vedic kundli</h2>
|
|
@@ -125,12 +119,8 @@ export class RoxyVedicKundli extends LitElement {
|
|
|
125
119
|
aria-label="Vedic birth chart with twelve sign houses"
|
|
126
120
|
>
|
|
127
121
|
<title>Vedic kundli</title>
|
|
128
|
-
${
|
|
129
|
-
${
|
|
130
|
-
isNorth
|
|
131
|
-
? houses.map((h) => renderNorthHouseGroup(h))
|
|
132
|
-
: houses.map((h) => renderSouthHouseGroup(h))
|
|
133
|
-
}
|
|
122
|
+
${frame}
|
|
123
|
+
${houses.map((h) => houseGroup(h))}
|
|
134
124
|
</svg>
|
|
135
125
|
</div>`;
|
|
136
126
|
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { css, html, LitElement, nothing } from 'lit';
|
|
2
|
+
import { customElement, property } from 'lit/decorators.js';
|
|
3
|
+
import { PLANET_GLYPH, SIGN_GLYPH } from '../tokens/index.js';
|
|
4
|
+
import type { BirthChartResponse } from '../types/index.js';
|
|
5
|
+
import { baseStyles } from '../utils/base-styles.js';
|
|
6
|
+
import { formatSignPosition } from '../utils/degree.js';
|
|
7
|
+
import { capitalize } from '../utils/string.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Fixed display order: Lagna pinned first as the chart frame, then the nine
|
|
11
|
+
* grahas in classical sequence. Any graha not in this list is appended.
|
|
12
|
+
*/
|
|
13
|
+
const GRAHA_ORDER = [
|
|
14
|
+
'Lagna',
|
|
15
|
+
'Sun',
|
|
16
|
+
'Moon',
|
|
17
|
+
'Mars',
|
|
18
|
+
'Mercury',
|
|
19
|
+
'Jupiter',
|
|
20
|
+
'Venus',
|
|
21
|
+
'Saturn',
|
|
22
|
+
'Rahu',
|
|
23
|
+
'Ketu',
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
type MetaEntry = BirthChartResponse['meta'][string];
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Vedic planetary positions table. Renders /vedic-astrology/birth-chart `meta`
|
|
30
|
+
* as the full reference-grade positions grid a practitioner reads alongside
|
|
31
|
+
* the kundli wheel: graha, rashi, exact degree, nakshatra and pada, nakshatra
|
|
32
|
+
* lord, bhava (house), Baladi avastha, and retrograde.
|
|
33
|
+
*/
|
|
34
|
+
@customElement('roxy-vedic-planets-table')
|
|
35
|
+
export class RoxyVedicPlanetsTable extends LitElement {
|
|
36
|
+
static styles = [
|
|
37
|
+
baseStyles,
|
|
38
|
+
css`
|
|
39
|
+
.wrap {
|
|
40
|
+
border: 1px solid var(--roxy-border, #e4e4e7);
|
|
41
|
+
border-radius: var(--roxy-radius-md, 8px);
|
|
42
|
+
background: var(--roxy-bg, #fff);
|
|
43
|
+
overflow: auto;
|
|
44
|
+
box-shadow: var(--roxy-shadow-sm);
|
|
45
|
+
}
|
|
46
|
+
.head {
|
|
47
|
+
padding: var(--roxy-space-md, 1rem);
|
|
48
|
+
border-bottom: 1px solid var(--roxy-border, #e4e4e7);
|
|
49
|
+
}
|
|
50
|
+
.title {
|
|
51
|
+
margin: 0;
|
|
52
|
+
font-size: var(--roxy-text-lg, 1.125rem);
|
|
53
|
+
font-weight: var(--roxy-weight-bold, 600);
|
|
54
|
+
}
|
|
55
|
+
table {
|
|
56
|
+
width: 100%;
|
|
57
|
+
border-collapse: collapse;
|
|
58
|
+
font-size: var(--roxy-text-sm, 0.875rem);
|
|
59
|
+
min-width: 620px;
|
|
60
|
+
}
|
|
61
|
+
thead {
|
|
62
|
+
background: color-mix(in srgb, var(--roxy-border, #e4e4e7) 20%, transparent);
|
|
63
|
+
}
|
|
64
|
+
th,
|
|
65
|
+
td {
|
|
66
|
+
padding: var(--roxy-space-sm, 0.5rem) var(--roxy-space-md, 1rem);
|
|
67
|
+
text-align: left;
|
|
68
|
+
white-space: nowrap;
|
|
69
|
+
}
|
|
70
|
+
th {
|
|
71
|
+
color: var(--roxy-muted, #71717a);
|
|
72
|
+
font-weight: var(--roxy-weight-bold, 600);
|
|
73
|
+
text-transform: uppercase;
|
|
74
|
+
font-size: var(--roxy-text-xs, 0.75rem);
|
|
75
|
+
letter-spacing: 0.04em;
|
|
76
|
+
}
|
|
77
|
+
tbody tr {
|
|
78
|
+
border-top: 1px solid var(--roxy-border, #e4e4e7);
|
|
79
|
+
}
|
|
80
|
+
tbody tr.lagna {
|
|
81
|
+
background: color-mix(in srgb, var(--roxy-accent, #f59e0b) 10%, transparent);
|
|
82
|
+
}
|
|
83
|
+
td.graha {
|
|
84
|
+
font-weight: var(--roxy-weight-bold, 600);
|
|
85
|
+
color: var(--roxy-fg, #0a0a0a);
|
|
86
|
+
}
|
|
87
|
+
.glyph {
|
|
88
|
+
margin-right: 0.4em;
|
|
89
|
+
color: var(--roxy-muted, #71717a);
|
|
90
|
+
}
|
|
91
|
+
/* On the tinted Lagna row the muted glyph drops below the WCAG AA
|
|
92
|
+
contrast floor, so use the accent foreground there instead. */
|
|
93
|
+
tbody tr.lagna .glyph {
|
|
94
|
+
color: var(--roxy-accent-fg, #b45309);
|
|
95
|
+
}
|
|
96
|
+
.retro {
|
|
97
|
+
color: var(--roxy-warning-fg, #9a3412);
|
|
98
|
+
font-size: var(--roxy-text-xs, 0.75rem);
|
|
99
|
+
font-weight: var(--roxy-weight-bold, 600);
|
|
100
|
+
}
|
|
101
|
+
.num {
|
|
102
|
+
font-variant-numeric: tabular-nums;
|
|
103
|
+
}
|
|
104
|
+
`,
|
|
105
|
+
];
|
|
106
|
+
|
|
107
|
+
@property({ attribute: false })
|
|
108
|
+
data: BirthChartResponse | null = null;
|
|
109
|
+
|
|
110
|
+
/** Ordered [name, entry] pairs: GRAHA_ORDER first, then any extras. */
|
|
111
|
+
private orderedRows(): Array<[string, MetaEntry]> {
|
|
112
|
+
const meta = this.data?.meta ?? {};
|
|
113
|
+
const seen = new Set<string>();
|
|
114
|
+
const rows: Array<[string, MetaEntry]> = [];
|
|
115
|
+
for (const name of GRAHA_ORDER) {
|
|
116
|
+
const entry = meta[name];
|
|
117
|
+
if (entry) {
|
|
118
|
+
rows.push([name, entry]);
|
|
119
|
+
seen.add(name);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
for (const [name, entry] of Object.entries(meta)) {
|
|
123
|
+
if (!seen.has(name)) rows.push([name, entry]);
|
|
124
|
+
}
|
|
125
|
+
return rows;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
render() {
|
|
129
|
+
if (!this.data?.meta)
|
|
130
|
+
return html`<div class="roxy-empty" role="status">No chart data</div>`;
|
|
131
|
+
const rows = this.orderedRows();
|
|
132
|
+
|
|
133
|
+
return html`<div class="wrap" aria-label="Vedic planetary positions" tabindex="0">
|
|
134
|
+
<header class="head">
|
|
135
|
+
<h2 class="title">Planetary positions</h2>
|
|
136
|
+
</header>
|
|
137
|
+
<table role="table">
|
|
138
|
+
<thead>
|
|
139
|
+
<tr>
|
|
140
|
+
<th scope="col">Graha</th>
|
|
141
|
+
<th scope="col">Rashi</th>
|
|
142
|
+
<th scope="col">Degree</th>
|
|
143
|
+
<th scope="col">Nakshatra</th>
|
|
144
|
+
<th scope="col">Pada</th>
|
|
145
|
+
<th scope="col">Nak. lord</th>
|
|
146
|
+
<th scope="col">House</th>
|
|
147
|
+
<th scope="col">Avastha</th>
|
|
148
|
+
<th scope="col">Retro</th>
|
|
149
|
+
</tr>
|
|
150
|
+
</thead>
|
|
151
|
+
<tbody>
|
|
152
|
+
${rows.map(([name, p]) => {
|
|
153
|
+
const isLagna = (p.graha ?? name) === 'Lagna';
|
|
154
|
+
const glyph = PLANET_GLYPH[capitalize(p.graha ?? name)] ?? '';
|
|
155
|
+
const signGlyph = SIGN_GLYPH[capitalize(p.rashi ?? '')] ?? '';
|
|
156
|
+
return html`<tr class=${isLagna ? 'lagna' : ''}>
|
|
157
|
+
<td class="graha">
|
|
158
|
+
${glyph ? html`<span class="glyph">${glyph}</span>` : nothing}${p.graha ?? name}
|
|
159
|
+
</td>
|
|
160
|
+
<td>
|
|
161
|
+
${signGlyph ? html`<span class="glyph">${signGlyph}</span>` : nothing}${p.rashi ?? ''}
|
|
162
|
+
</td>
|
|
163
|
+
<td class="num">
|
|
164
|
+
${typeof p.longitude === 'number' ? formatSignPosition(p.longitude) : ''}
|
|
165
|
+
</td>
|
|
166
|
+
<td>${p.nakshatra?.name ?? ''}</td>
|
|
167
|
+
<td class="num">${p.nakshatra?.pada ?? ''}</td>
|
|
168
|
+
<td>${p.nakshatra?.lord ?? ''}</td>
|
|
169
|
+
<td class="num">${typeof p.house === 'number' ? p.house : ''}</td>
|
|
170
|
+
<td>${p.awastha ?? ''}</td>
|
|
171
|
+
<td>${p.isRetrograde ? html`<span class="retro">R</span>` : nothing}</td>
|
|
172
|
+
</tr>`;
|
|
173
|
+
})}
|
|
174
|
+
</tbody>
|
|
175
|
+
</table>
|
|
176
|
+
</div>`;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
declare global {
|
|
181
|
+
interface HTMLElementTagNameMap {
|
|
182
|
+
'roxy-vedic-planets-table': RoxyVedicPlanetsTable;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { css, html, LitElement, nothing } from 'lit';
|
|
2
|
+
import { customElement, property } from 'lit/decorators.js';
|
|
3
|
+
import { PLANET_GLYPH, SIGN_GLYPH } from '../tokens/index.js';
|
|
4
|
+
import type { NatalChartResponse } from '../types/index.js';
|
|
5
|
+
import { baseStyles } from '../utils/base-styles.js';
|
|
6
|
+
import { formatSignPosition } from '../utils/degree.js';
|
|
7
|
+
import { formatNumber } from '../utils/format.js';
|
|
8
|
+
import { capitalize } from '../utils/string.js';
|
|
9
|
+
|
|
10
|
+
/** A body or point row, normalized so planets and the four angles share a table. */
|
|
11
|
+
interface BodyRow {
|
|
12
|
+
name: string;
|
|
13
|
+
sign?: string;
|
|
14
|
+
longitude?: number;
|
|
15
|
+
house?: number;
|
|
16
|
+
speed?: number;
|
|
17
|
+
isRetrograde?: boolean;
|
|
18
|
+
/** True for the chart angles (ASC, MC, Part of Fortune, Vertex). */
|
|
19
|
+
isPoint?: boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Western planetary positions table. Renders a /astrology/natal-chart response
|
|
24
|
+
* as the reference-grade positions grid astrologers read alongside the wheel:
|
|
25
|
+
* every body with its sign, exact degree, house, and daily motion, followed by
|
|
26
|
+
* the four chart points (Ascendant, Midheaven, Part of Fortune, Vertex).
|
|
27
|
+
*/
|
|
28
|
+
@customElement('roxy-western-planets-table')
|
|
29
|
+
export class RoxyWesternPlanetsTable extends LitElement {
|
|
30
|
+
static styles = [
|
|
31
|
+
baseStyles,
|
|
32
|
+
css`
|
|
33
|
+
.wrap {
|
|
34
|
+
border: 1px solid var(--roxy-border, #e4e4e7);
|
|
35
|
+
border-radius: var(--roxy-radius-md, 8px);
|
|
36
|
+
background: var(--roxy-bg, #fff);
|
|
37
|
+
overflow: auto;
|
|
38
|
+
box-shadow: var(--roxy-shadow-sm);
|
|
39
|
+
}
|
|
40
|
+
.head {
|
|
41
|
+
padding: var(--roxy-space-md, 1rem);
|
|
42
|
+
border-bottom: 1px solid var(--roxy-border, #e4e4e7);
|
|
43
|
+
}
|
|
44
|
+
.title {
|
|
45
|
+
margin: 0;
|
|
46
|
+
font-size: var(--roxy-text-lg, 1.125rem);
|
|
47
|
+
font-weight: var(--roxy-weight-bold, 600);
|
|
48
|
+
}
|
|
49
|
+
table {
|
|
50
|
+
width: 100%;
|
|
51
|
+
border-collapse: collapse;
|
|
52
|
+
font-size: var(--roxy-text-sm, 0.875rem);
|
|
53
|
+
min-width: 460px;
|
|
54
|
+
}
|
|
55
|
+
thead {
|
|
56
|
+
background: color-mix(in srgb, var(--roxy-border, #e4e4e7) 20%, transparent);
|
|
57
|
+
}
|
|
58
|
+
th,
|
|
59
|
+
td {
|
|
60
|
+
padding: var(--roxy-space-sm, 0.5rem) var(--roxy-space-md, 1rem);
|
|
61
|
+
text-align: left;
|
|
62
|
+
white-space: nowrap;
|
|
63
|
+
}
|
|
64
|
+
th {
|
|
65
|
+
color: var(--roxy-muted, #71717a);
|
|
66
|
+
font-weight: var(--roxy-weight-bold, 600);
|
|
67
|
+
text-transform: uppercase;
|
|
68
|
+
font-size: var(--roxy-text-xs, 0.75rem);
|
|
69
|
+
letter-spacing: 0.04em;
|
|
70
|
+
}
|
|
71
|
+
tbody tr {
|
|
72
|
+
border-top: 1px solid var(--roxy-border, #e4e4e7);
|
|
73
|
+
}
|
|
74
|
+
tbody tr.point {
|
|
75
|
+
background: color-mix(in srgb, var(--roxy-accent, #f59e0b) 8%, transparent);
|
|
76
|
+
}
|
|
77
|
+
td.body {
|
|
78
|
+
font-weight: var(--roxy-weight-bold, 600);
|
|
79
|
+
color: var(--roxy-fg, #0a0a0a);
|
|
80
|
+
}
|
|
81
|
+
.glyph {
|
|
82
|
+
margin-right: 0.4em;
|
|
83
|
+
color: var(--roxy-muted, #71717a);
|
|
84
|
+
}
|
|
85
|
+
.retro {
|
|
86
|
+
color: var(--roxy-danger, #dc2626);
|
|
87
|
+
font-weight: var(--roxy-weight-bold, 600);
|
|
88
|
+
}
|
|
89
|
+
.num {
|
|
90
|
+
font-variant-numeric: tabular-nums;
|
|
91
|
+
}
|
|
92
|
+
`,
|
|
93
|
+
];
|
|
94
|
+
|
|
95
|
+
@property({ attribute: false })
|
|
96
|
+
data: NatalChartResponse | null = null;
|
|
97
|
+
|
|
98
|
+
/** Build the ordered row list: the planets array, then the four chart points. */
|
|
99
|
+
private rows(): BodyRow[] {
|
|
100
|
+
const d = this.data;
|
|
101
|
+
if (!d) return [];
|
|
102
|
+
const rows: BodyRow[] = (d.planets ?? []).map((p) => ({
|
|
103
|
+
name: p.name,
|
|
104
|
+
sign: p.sign,
|
|
105
|
+
longitude: p.longitude,
|
|
106
|
+
house: p.house,
|
|
107
|
+
speed: p.speed,
|
|
108
|
+
isRetrograde: p.isRetrograde,
|
|
109
|
+
}));
|
|
110
|
+
for (const [name, point] of [
|
|
111
|
+
['Ascendant', d.ascendant],
|
|
112
|
+
['Midheaven', d.midheaven],
|
|
113
|
+
['Part of Fortune', d.partOfFortune],
|
|
114
|
+
['Vertex', d.vertex],
|
|
115
|
+
] as const) {
|
|
116
|
+
if (point) {
|
|
117
|
+
rows.push({
|
|
118
|
+
name,
|
|
119
|
+
sign: point.sign,
|
|
120
|
+
longitude: point.longitude,
|
|
121
|
+
isPoint: true,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return rows;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
render() {
|
|
129
|
+
if (!this.data?.planets)
|
|
130
|
+
return html`<div class="roxy-empty" role="status">No chart data</div>`;
|
|
131
|
+
const rows = this.rows();
|
|
132
|
+
|
|
133
|
+
return html`<div class="wrap" aria-label="Western planetary positions" tabindex="0">
|
|
134
|
+
<header class="head">
|
|
135
|
+
<h2 class="title">Planetary positions</h2>
|
|
136
|
+
</header>
|
|
137
|
+
<table role="table">
|
|
138
|
+
<thead>
|
|
139
|
+
<tr>
|
|
140
|
+
<th scope="col">Body</th>
|
|
141
|
+
<th scope="col">Sign</th>
|
|
142
|
+
<th scope="col">Degree</th>
|
|
143
|
+
<th scope="col">House</th>
|
|
144
|
+
<th scope="col">Motion</th>
|
|
145
|
+
</tr>
|
|
146
|
+
</thead>
|
|
147
|
+
<tbody>
|
|
148
|
+
${rows.map((r) => {
|
|
149
|
+
const glyph = PLANET_GLYPH[capitalize(r.name)] ?? '';
|
|
150
|
+
const signGlyph = SIGN_GLYPH[capitalize(r.sign ?? '')] ?? '';
|
|
151
|
+
const speed =
|
|
152
|
+
typeof r.speed === 'number' ? formatNumber(r.speed, 3) : '';
|
|
153
|
+
return html`<tr class=${r.isPoint ? 'point' : ''}>
|
|
154
|
+
<td class="body">
|
|
155
|
+
${glyph ? html`<span class="glyph">${glyph}</span>` : nothing}${r.name}
|
|
156
|
+
</td>
|
|
157
|
+
<td>
|
|
158
|
+
${signGlyph ? html`<span class="glyph">${signGlyph}</span>` : nothing}${r.sign ?? ''}
|
|
159
|
+
</td>
|
|
160
|
+
<td class="num">
|
|
161
|
+
${typeof r.longitude === 'number' ? formatSignPosition(r.longitude) : ''}
|
|
162
|
+
</td>
|
|
163
|
+
<td class="num">${typeof r.house === 'number' ? r.house : ''}</td>
|
|
164
|
+
<td class="num">
|
|
165
|
+
${speed ? html`${speed}°/day` : nothing}
|
|
166
|
+
${r.isRetrograde ? html`<span class="retro"> ℞</span>` : nothing}
|
|
167
|
+
</td>
|
|
168
|
+
</tr>`;
|
|
169
|
+
})}
|
|
170
|
+
</tbody>
|
|
171
|
+
</table>
|
|
172
|
+
</div>`;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
declare global {
|
|
177
|
+
interface HTMLElementTagNameMap {
|
|
178
|
+
'roxy-western-planets-table': RoxyWesternPlanetsTable;
|
|
179
|
+
}
|
|
180
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -21,9 +21,12 @@ export { RoxyGunaMilan } from './components/guna-milan.js';
|
|
|
21
21
|
// I Ching
|
|
22
22
|
export { RoxyHexagram } from './components/hexagram.js';
|
|
23
23
|
export { RoxyHoroscopeCard } from './components/horoscope-card.js';
|
|
24
|
+
export { RoxyKpChart } from './components/kp-chart.js';
|
|
24
25
|
export { RoxyKpPlanetsTable } from './components/kp-planets-table.js';
|
|
26
|
+
export { RoxyKpRulingPlanets } from './components/kp-ruling-planets.js';
|
|
25
27
|
export { RoxyLocationSearch } from './components/location-search.js';
|
|
26
28
|
export { RoxyMoonPhase } from './components/moon-phase.js';
|
|
29
|
+
export { RoxyNakshatraCard } from './components/nakshatra-card.js';
|
|
27
30
|
// Western astrology
|
|
28
31
|
export { RoxyNatalChart } from './components/natal-chart.js';
|
|
29
32
|
// Numerology
|
|
@@ -37,6 +40,8 @@ export { RoxyTarotSpread } from './components/tarot-spread.js';
|
|
|
37
40
|
export { RoxyTransitsTable } from './components/transits-table.js';
|
|
38
41
|
// Vedic astrology
|
|
39
42
|
export { RoxyVedicKundli } from './components/vedic-kundli.js';
|
|
43
|
+
export { RoxyVedicPlanetsTable } from './components/vedic-planets-table.js';
|
|
44
|
+
export { RoxyWesternPlanetsTable } from './components/western-planets-table.js';
|
|
40
45
|
export { RoxyYogaList } from './components/yoga-list.js';
|
|
41
46
|
|
|
42
47
|
import { ROXY_COMPONENTS, type RoxyComponentSlug } from './manifest.js';
|