@roxyapi/ui 0.1.2 → 0.2.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 +6 -0
- package/README.md +327 -14
- package/THEMING.md +24 -7
- package/dist/cdn/components/ashtakavarga-grid.js +349 -0
- package/dist/cdn/components/ashtakavarga-grid.js.map +7 -0
- package/dist/cdn/components/biorhythm-chart.js +15 -22
- package/dist/cdn/components/biorhythm-chart.js.map +3 -3
- package/dist/cdn/components/choghadiya-grid.js +239 -0
- package/dist/cdn/components/choghadiya-grid.js.map +7 -0
- package/dist/cdn/components/compatibility-card.js +36 -34
- package/dist/cdn/components/compatibility-card.js.map +4 -4
- package/dist/cdn/components/dasha-timeline.js +35 -39
- package/dist/cdn/components/dasha-timeline.js.map +4 -4
- package/dist/cdn/components/data.js +9 -9
- package/dist/cdn/components/data.js.map +4 -4
- package/dist/cdn/components/divisional-chart.js +279 -0
- package/dist/cdn/components/divisional-chart.js.map +7 -0
- package/dist/cdn/components/dosha-card.js +49 -49
- package/dist/cdn/components/dosha-card.js.map +3 -3
- package/dist/cdn/components/endpoint-form.js +47 -28
- package/dist/cdn/components/endpoint-form.js.map +4 -4
- package/dist/cdn/components/guna-milan.js +66 -24
- package/dist/cdn/components/guna-milan.js.map +4 -4
- package/dist/cdn/components/hexagram.js +26 -26
- package/dist/cdn/components/hexagram.js.map +3 -3
- package/dist/cdn/components/horoscope-card.js +47 -40
- package/dist/cdn/components/horoscope-card.js.map +4 -4
- package/dist/cdn/components/kp-planets-table.js +10 -10
- package/dist/cdn/components/kp-planets-table.js.map +4 -4
- package/dist/cdn/components/location-search.js +6 -6
- package/dist/cdn/components/location-search.js.map +3 -3
- package/dist/cdn/components/moon-phase.js +18 -18
- package/dist/cdn/components/moon-phase.js.map +4 -4
- package/dist/cdn/components/natal-chart.js +240 -24
- package/dist/cdn/components/natal-chart.js.map +4 -4
- package/dist/cdn/components/numerology-card.js +40 -31
- package/dist/cdn/components/numerology-card.js.map +4 -4
- package/dist/cdn/components/panchang-table.js +30 -30
- package/dist/cdn/components/panchang-table.js.map +4 -4
- package/dist/cdn/components/shadbala-table.js +312 -0
- package/dist/cdn/components/shadbala-table.js.map +7 -0
- package/dist/cdn/components/synastry-chart.js +129 -39
- package/dist/cdn/components/synastry-chart.js.map +4 -4
- package/dist/cdn/components/tarot-card.js +49 -20
- package/dist/cdn/components/tarot-card.js.map +3 -3
- package/dist/cdn/components/tarot-spread.js +43 -27
- package/dist/cdn/components/tarot-spread.js.map +3 -3
- package/dist/cdn/components/transits-table.js +391 -0
- package/dist/cdn/components/transits-table.js.map +7 -0
- package/dist/cdn/components/vedic-kundli.js +63 -27
- package/dist/cdn/components/vedic-kundli.js.map +4 -4
- package/dist/cdn/components/yoga-list.js +334 -0
- package/dist/cdn/components/yoga-list.js.map +7 -0
- package/dist/cdn/roxy-ui.js +2104 -544
- package/dist/cdn/roxy-ui.js.map +4 -4
- package/dist/components/ashtakavarga-grid.d.ts +26 -0
- package/dist/components/ashtakavarga-grid.d.ts.map +1 -0
- package/dist/components/ashtakavarga-grid.js +457 -0
- package/dist/components/ashtakavarga-grid.js.map +7 -0
- package/dist/components/biorhythm-chart.d.ts +2 -46
- package/dist/components/biorhythm-chart.d.ts.map +1 -1
- package/dist/components/biorhythm-chart.js +24 -23
- package/dist/components/biorhythm-chart.js.map +2 -2
- package/dist/components/choghadiya-grid.d.ts +19 -0
- package/dist/components/choghadiya-grid.d.ts.map +1 -0
- package/dist/components/choghadiya-grid.js +304 -0
- package/dist/components/choghadiya-grid.js.map +7 -0
- package/dist/components/compatibility-card.d.ts +2 -27
- package/dist/components/compatibility-card.d.ts.map +1 -1
- package/dist/components/compatibility-card.js +50 -29
- package/dist/components/compatibility-card.js.map +3 -3
- package/dist/components/dasha-timeline.d.ts +2 -31
- package/dist/components/dasha-timeline.d.ts.map +1 -1
- package/dist/components/dasha-timeline.js +32 -30
- package/dist/components/dasha-timeline.js.map +3 -3
- package/dist/components/data.d.ts +11 -7
- package/dist/components/data.d.ts.map +1 -1
- package/dist/components/data.js +16 -6
- package/dist/components/data.js.map +3 -3
- package/dist/components/divisional-chart.d.ts +20 -0
- package/dist/components/divisional-chart.d.ts.map +1 -0
- package/dist/components/divisional-chart.js +471 -0
- package/dist/components/divisional-chart.js.map +7 -0
- package/dist/components/dosha-card.d.ts +2 -16
- package/dist/components/dosha-card.d.ts.map +1 -1
- package/dist/components/dosha-card.js +45 -43
- package/dist/components/dosha-card.js.map +2 -2
- package/dist/components/endpoint-form.d.ts +2 -0
- package/dist/components/endpoint-form.d.ts.map +1 -1
- package/dist/components/endpoint-form.js +71 -11
- package/dist/components/endpoint-form.js.map +3 -3
- package/dist/components/guna-milan.d.ts +2 -20
- package/dist/components/guna-milan.d.ts.map +1 -1
- package/dist/components/guna-milan.js +79 -20
- package/dist/components/guna-milan.js.map +4 -4
- package/dist/components/hexagram.d.ts +3 -27
- package/dist/components/hexagram.d.ts.map +1 -1
- package/dist/components/hexagram.js +48 -15
- package/dist/components/hexagram.js.map +2 -2
- package/dist/components/horoscope-card.d.ts +2 -20
- package/dist/components/horoscope-card.d.ts.map +1 -1
- package/dist/components/horoscope-card.js +54 -18
- package/dist/components/horoscope-card.js.map +3 -3
- package/dist/components/kp-planets-table.d.ts +2 -21
- package/dist/components/kp-planets-table.d.ts.map +1 -1
- package/dist/components/kp-planets-table.js +10 -4
- package/dist/components/kp-planets-table.js.map +3 -3
- package/dist/components/location-search.d.ts +5 -14
- package/dist/components/location-search.d.ts.map +1 -1
- package/dist/components/location-search.js +45 -5
- package/dist/components/location-search.js.map +2 -2
- package/dist/components/moon-phase.d.ts +4 -21
- package/dist/components/moon-phase.d.ts.map +1 -1
- package/dist/components/moon-phase.js +34 -4
- package/dist/components/moon-phase.js.map +3 -3
- package/dist/components/natal-chart.d.ts +9 -43
- package/dist/components/natal-chart.d.ts.map +1 -1
- package/dist/components/natal-chart.js +346 -79
- package/dist/components/natal-chart.js.map +3 -3
- package/dist/components/numerology-card.d.ts +5 -37
- package/dist/components/numerology-card.d.ts.map +1 -1
- package/dist/components/numerology-card.js +58 -30
- package/dist/components/numerology-card.js.map +3 -3
- package/dist/components/panchang-table.d.ts +3 -62
- package/dist/components/panchang-table.d.ts.map +1 -1
- package/dist/components/panchang-table.js +62 -32
- package/dist/components/panchang-table.js.map +3 -3
- package/dist/components/shadbala-table.d.ts +18 -0
- package/dist/components/shadbala-table.d.ts.map +1 -0
- package/dist/components/shadbala-table.js +400 -0
- package/dist/components/shadbala-table.js.map +7 -0
- package/dist/components/synastry-chart.d.ts +9 -28
- package/dist/components/synastry-chart.d.ts.map +1 -1
- package/dist/components/synastry-chart.js +201 -56
- package/dist/components/synastry-chart.js.map +3 -3
- package/dist/components/tarot-card.d.ts +5 -29
- package/dist/components/tarot-card.d.ts.map +1 -1
- package/dist/components/tarot-card.js +59 -20
- package/dist/components/tarot-card.js.map +2 -2
- package/dist/components/tarot-spread.d.ts +2 -24
- package/dist/components/tarot-spread.d.ts.map +1 -1
- package/dist/components/tarot-spread.js +39 -13
- package/dist/components/tarot-spread.js.map +2 -2
- package/dist/components/transits-table.d.ts +21 -0
- package/dist/components/transits-table.d.ts.map +1 -0
- package/dist/components/transits-table.js +515 -0
- package/dist/components/transits-table.js.map +7 -0
- package/dist/components/vedic-kundli.d.ts +5 -28
- package/dist/components/vedic-kundli.d.ts.map +1 -1
- package/dist/components/vedic-kundli.js +147 -83
- package/dist/components/vedic-kundli.js.map +3 -3
- package/dist/components/yoga-list.d.ts +29 -0
- package/dist/components/yoga-list.d.ts.map +1 -0
- package/dist/components/yoga-list.js +389 -0
- package/dist/components/yoga-list.js.map +7 -0
- package/dist/index.cjs +3693 -1180
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +11 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3709 -1196
- package/dist/index.js.map +4 -4
- package/dist/manifest.d.ts +43 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.json +7 -2
- package/dist/styles/tokens.css +73 -1
- package/dist/tokens/index.d.ts +6 -0
- package/dist/tokens/index.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/types.gen.d.ts +27811 -0
- package/dist/types/types.gen.d.ts.map +1 -0
- package/dist/utils/debounce.d.ts +9 -1
- package/dist/utils/debounce.d.ts.map +1 -1
- package/dist/utils/format.d.ts +29 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/kundli-render.d.ts +63 -0
- package/dist/utils/kundli-render.d.ts.map +1 -0
- package/dist/utils/string.d.ts +14 -0
- package/dist/utils/string.d.ts.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/package.json +7 -1
- package/src/components/ashtakavarga-grid.ts +354 -0
- package/src/components/biorhythm-chart.ts +39 -84
- package/src/components/choghadiya-grid.ts +185 -0
- package/src/components/compatibility-card.ts +85 -52
- package/src/components/dasha-timeline.ts +55 -73
- package/src/components/data.ts +28 -16
- package/src/components/divisional-chart.ts +214 -0
- package/src/components/dosha-card.ts +72 -68
- package/src/components/endpoint-form.ts +80 -18
- package/src/components/guna-milan.ts +87 -47
- package/src/components/hexagram.ts +53 -43
- package/src/components/horoscope-card.ts +59 -43
- package/src/components/kp-planets-table.ts +8 -27
- package/src/components/location-search.ts +47 -23
- package/src/components/moon-phase.ts +28 -25
- package/src/components/natal-chart.ts +364 -110
- package/src/components/numerology-card.ts +86 -84
- package/src/components/panchang-table.ts +40 -78
- package/src/components/shadbala-table.ts +286 -0
- package/src/components/synastry-chart.ts +213 -97
- package/src/components/tarot-card.ts +76 -62
- package/src/components/tarot-spread.ts +72 -45
- package/src/components/transits-table.ts +350 -0
- package/src/components/vedic-kundli.ts +59 -173
- package/src/components/yoga-list.ts +328 -0
- package/src/index.ts +18 -26
- package/src/manifest.ts +340 -0
- package/src/styles/tokens.css +73 -1
- package/src/tokens/index.ts +14 -0
- package/src/types/types.gen.ts +3 -3
- package/src/utils/debounce.ts +23 -4
- package/src/utils/format.ts +75 -0
- package/src/utils/kundli-render.ts +197 -0
- package/src/utils/string.ts +23 -0
- package/src/version.ts +2 -0
- package/dist/utils/motion.d.ts +0 -13
- package/dist/utils/motion.d.ts.map +0 -1
- package/src/utils/motion.ts +0 -18
|
@@ -1,113 +1,30 @@
|
|
|
1
|
-
import { css, html, LitElement
|
|
1
|
+
import { css, html, LitElement } from 'lit';
|
|
2
2
|
import { customElement, property } from 'lit/decorators.js';
|
|
3
|
-
import {
|
|
3
|
+
import { RASHI_KEYS } from '../tokens/index.js';
|
|
4
|
+
import type { BirthChartResponse } from '../types/index.js';
|
|
4
5
|
import { baseStyles } from '../utils/base-styles.js';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
longitude?: number;
|
|
21
|
-
isRetrograde?: boolean;
|
|
22
|
-
}>;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
interface KundliHouse {
|
|
26
|
-
house: number;
|
|
27
|
-
sign: string;
|
|
28
|
-
planets: string[];
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
interface KundliData {
|
|
32
|
-
meta?: KundliMeta;
|
|
33
|
-
houses?: Array<{
|
|
34
|
-
house?: number;
|
|
35
|
-
number?: number;
|
|
36
|
-
sign?: string;
|
|
37
|
-
planets?: string[];
|
|
38
|
-
}>;
|
|
39
|
-
combustion?: unknown[];
|
|
40
|
-
planetaryWar?: unknown[];
|
|
41
|
-
[rashi: string]: unknown;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const SOUTH_HOUSE_CENTERS: Record<number, { x: number; y: number }> = {
|
|
45
|
-
1: { x: 150, y: 58 },
|
|
46
|
-
2: { x: 205, y: 52 },
|
|
47
|
-
3: { x: 253, y: 112 },
|
|
48
|
-
4: { x: 243, y: 150 },
|
|
49
|
-
5: { x: 253, y: 188 },
|
|
50
|
-
6: { x: 205, y: 248 },
|
|
51
|
-
7: { x: 150, y: 242 },
|
|
52
|
-
8: { x: 95, y: 248 },
|
|
53
|
-
9: { x: 47, y: 188 },
|
|
54
|
-
10: { x: 57, y: 150 },
|
|
55
|
-
11: { x: 47, y: 112 },
|
|
56
|
-
12: { x: 95, y: 52 },
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const SOUTH_SIGN_POSITIONS: Record<number, { x: number; y: number }> = {
|
|
60
|
-
1: { x: 150, y: 35 },
|
|
61
|
-
2: { x: 222, y: 40 },
|
|
62
|
-
3: { x: 265, y: 100 },
|
|
63
|
-
4: { x: 265, y: 150 },
|
|
64
|
-
5: { x: 265, y: 200 },
|
|
65
|
-
6: { x: 222, y: 260 },
|
|
66
|
-
7: { x: 150, y: 265 },
|
|
67
|
-
8: { x: 78, y: 260 },
|
|
68
|
-
9: { x: 35, y: 200 },
|
|
69
|
-
10: { x: 35, y: 150 },
|
|
70
|
-
11: { x: 35, y: 100 },
|
|
71
|
-
12: { x: 78, y: 40 },
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
const RASHI_KEYS = [
|
|
75
|
-
'aries',
|
|
76
|
-
'taurus',
|
|
77
|
-
'gemini',
|
|
78
|
-
'cancer',
|
|
79
|
-
'leo',
|
|
80
|
-
'virgo',
|
|
81
|
-
'libra',
|
|
82
|
-
'scorpio',
|
|
83
|
-
'sagittarius',
|
|
84
|
-
'capricorn',
|
|
85
|
-
'aquarius',
|
|
86
|
-
'pisces',
|
|
87
|
-
] as const;
|
|
88
|
-
|
|
89
|
-
const RASHI_TO_SIGN: Record<string, string> = {
|
|
90
|
-
aries: 'Aries',
|
|
91
|
-
taurus: 'Taurus',
|
|
92
|
-
gemini: 'Gemini',
|
|
93
|
-
cancer: 'Cancer',
|
|
94
|
-
leo: 'Leo',
|
|
95
|
-
virgo: 'Virgo',
|
|
96
|
-
libra: 'Libra',
|
|
97
|
-
scorpio: 'Scorpio',
|
|
98
|
-
sagittarius: 'Sagittarius',
|
|
99
|
-
capricorn: 'Capricorn',
|
|
100
|
-
aquarius: 'Aquarius',
|
|
101
|
-
pisces: 'Pisces',
|
|
102
|
-
};
|
|
6
|
+
import type { HouseDef } from '../utils/kundli-render.js';
|
|
7
|
+
import {
|
|
8
|
+
RASHI_TO_SIGN,
|
|
9
|
+
renderNorthFrame,
|
|
10
|
+
renderNorthHouseGroup,
|
|
11
|
+
renderSouthFrame,
|
|
12
|
+
renderSouthHouseGroup,
|
|
13
|
+
} from '../utils/kundli-render.js';
|
|
14
|
+
|
|
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>;
|
|
103
21
|
|
|
104
22
|
/**
|
|
105
23
|
* Vedic kundli (D1 Rashi chart). South Indian style by default. Pass `data`
|
|
106
|
-
* from /vedic-astrology/birth-chart. North Indian style via
|
|
24
|
+
* from /vedic-astrology/birth-chart. North Indian style via chartStyle="north".
|
|
107
25
|
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
* DOM color-probing hook in favor of CSS custom properties on :host.
|
|
26
|
+
* Theming flows through CSS custom properties on :host, so the chart adopts
|
|
27
|
+
* the host page palette without runtime color probing.
|
|
111
28
|
*/
|
|
112
29
|
@customElement('roxy-vedic-kundli')
|
|
113
30
|
export class RoxyVedicKundli extends LitElement {
|
|
@@ -145,43 +62,50 @@ export class RoxyVedicKundli extends LitElement {
|
|
|
145
62
|
font-weight: 600;
|
|
146
63
|
font-family: var(--roxy-font-sans);
|
|
147
64
|
}
|
|
65
|
+
.house-num {
|
|
66
|
+
fill: var(--roxy-muted, #71717a);
|
|
67
|
+
font-size: 9px;
|
|
68
|
+
font-weight: 400;
|
|
69
|
+
font-family: var(--roxy-font-sans);
|
|
70
|
+
}
|
|
71
|
+
.lagna-marker {
|
|
72
|
+
fill: var(--roxy-accent-fg, #b45309);
|
|
73
|
+
font-size: 8px;
|
|
74
|
+
font-weight: 700;
|
|
75
|
+
font-family: var(--roxy-font-sans);
|
|
76
|
+
letter-spacing: 0.05em;
|
|
77
|
+
}
|
|
78
|
+
.lagna-bg {
|
|
79
|
+
fill: color-mix(in srgb, var(--roxy-accent, #f59e0b) 12%, transparent);
|
|
80
|
+
stroke: color-mix(in srgb, var(--roxy-accent, #f59e0b) 45%, transparent);
|
|
81
|
+
stroke-width: 0.8;
|
|
82
|
+
}
|
|
148
83
|
`,
|
|
149
84
|
];
|
|
150
85
|
|
|
151
86
|
@property({ attribute: false })
|
|
152
|
-
data:
|
|
87
|
+
data: BirthChartResponse | null = null;
|
|
153
88
|
|
|
154
89
|
@property({ type: String, reflect: true, attribute: 'chart-style' })
|
|
155
90
|
chartStyle: 'south' | 'north' = 'south';
|
|
156
91
|
|
|
157
|
-
private buildHouses():
|
|
92
|
+
private buildHouses(): HouseDef[] {
|
|
158
93
|
if (!this.data) return [];
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
for (const h of this.data.houses) {
|
|
163
|
-
houses.push({
|
|
164
|
-
house: (h.house ?? h.number ?? houses.length + 1) as number,
|
|
165
|
-
sign: h.sign ?? '',
|
|
166
|
-
planets: h.planets ?? [],
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
if (houses.length > 0) return houses;
|
|
170
|
-
}
|
|
171
|
-
// Otherwise read the rashi buckets and project them as houses 1..12
|
|
172
|
-
// keyed by sign order. Lagna-anchored ordering would require knowing
|
|
173
|
-
// the ascendant rashi; we render rashi buckets directly which is the
|
|
174
|
-
// canonical South Indian layout.
|
|
94
|
+
const data = this.data as BirthChartByRashi;
|
|
95
|
+
const lagnaSign = this.data?.meta?.Lagna?.rashi ?? '';
|
|
96
|
+
const houses: HouseDef[] = [];
|
|
175
97
|
for (let i = 0; i < 12; i++) {
|
|
176
98
|
const key = RASHI_KEYS[i];
|
|
177
|
-
const bucket =
|
|
178
|
-
const planets = (bucket?.signs ?? [])
|
|
179
|
-
|
|
180
|
-
.filter(Boolean);
|
|
99
|
+
const bucket = data[key];
|
|
100
|
+
const planets = (bucket?.signs ?? []).map((p) => p.graha).filter(Boolean);
|
|
101
|
+
const sign = RASHI_TO_SIGN[key] ?? '';
|
|
181
102
|
houses.push({
|
|
182
|
-
|
|
183
|
-
sign
|
|
103
|
+
number: i + 1,
|
|
104
|
+
sign,
|
|
184
105
|
planets,
|
|
106
|
+
isLagna: lagnaSign
|
|
107
|
+
? lagnaSign.toLowerCase() === sign.toLowerCase()
|
|
108
|
+
: false,
|
|
185
109
|
});
|
|
186
110
|
}
|
|
187
111
|
return houses;
|
|
@@ -191,6 +115,7 @@ export class RoxyVedicKundli extends LitElement {
|
|
|
191
115
|
if (!this.data)
|
|
192
116
|
return html`<div class="roxy-empty" role="status">No kundli data</div>`;
|
|
193
117
|
const houses = this.buildHouses();
|
|
118
|
+
const isNorth = this.chartStyle === 'north';
|
|
194
119
|
|
|
195
120
|
return html`<div class="wrap">
|
|
196
121
|
<h2 class="title">Vedic kundli</h2>
|
|
@@ -200,56 +125,17 @@ export class RoxyVedicKundli extends LitElement {
|
|
|
200
125
|
aria-label="Vedic birth chart with twelve sign houses"
|
|
201
126
|
>
|
|
202
127
|
<title>Vedic kundli</title>
|
|
203
|
-
|
|
204
|
-
<polygon
|
|
205
|
-
class="line"
|
|
206
|
-
points="220,80 220,220 80,220 80,80"
|
|
207
|
-
stroke-width="1"
|
|
208
|
-
fill="none"
|
|
209
|
-
/>
|
|
210
|
-
<line class="line" x1="150" y1="10" x2="80" y2="80" stroke-width="1" />
|
|
211
|
-
<line class="line" x1="150" y1="10" x2="220" y2="80" stroke-width="1" />
|
|
212
|
-
<line class="line" x1="290" y1="150" x2="220" y2="80" stroke-width="1" />
|
|
213
|
-
<line class="line" x1="290" y1="150" x2="220" y2="220" stroke-width="1" />
|
|
214
|
-
<line class="line" x1="150" y1="290" x2="220" y2="220" stroke-width="1" />
|
|
215
|
-
<line class="line" x1="150" y1="290" x2="80" y2="220" stroke-width="1" />
|
|
216
|
-
<line class="line" x1="10" y1="150" x2="80" y2="220" stroke-width="1" />
|
|
217
|
-
<line class="line" x1="10" y1="150" x2="80" y2="80" stroke-width="1" />
|
|
218
|
-
${houses.map((h) => this.renderHouseGroup(h))}
|
|
219
|
-
</svg>
|
|
220
|
-
</div>`;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
private renderHouseGroup(h: KundliHouse) {
|
|
224
|
-
const center = SOUTH_HOUSE_CENTERS[h.house];
|
|
225
|
-
const signPos = SOUTH_SIGN_POSITIONS[h.house];
|
|
226
|
-
if (!center || !signPos) return nothing;
|
|
227
|
-
const signAbbr = SIGN_ABBR[h.sign] ?? '';
|
|
228
|
-
const planets = h.planets ?? [];
|
|
229
|
-
return svg`
|
|
230
|
-
<g>
|
|
128
|
+
${isNorth ? renderNorthFrame() : renderSouthFrame()}
|
|
231
129
|
${
|
|
232
|
-
|
|
233
|
-
?
|
|
234
|
-
:
|
|
130
|
+
isNorth
|
|
131
|
+
? houses.map((h) => renderNorthHouseGroup(h))
|
|
132
|
+
: houses.map((h) => renderSouthHouseGroup(h))
|
|
235
133
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
const lineHeight = 13;
|
|
239
|
-
const startY = center.y - ((planets.length - 1) * lineHeight) / 2;
|
|
240
|
-
const yPos = startY + j * lineHeight;
|
|
241
|
-
return svg`<text class="planet-text" x=${center.x} y=${yPos} text-anchor="middle" dominant-baseline="central">${abbr}</text>`;
|
|
242
|
-
})}
|
|
243
|
-
</g>
|
|
244
|
-
`;
|
|
134
|
+
</svg>
|
|
135
|
+
</div>`;
|
|
245
136
|
}
|
|
246
137
|
}
|
|
247
138
|
|
|
248
|
-
function capitalize(s: string): string {
|
|
249
|
-
if (!s) return '';
|
|
250
|
-
return s.charAt(0).toUpperCase() + s.slice(1).toLowerCase();
|
|
251
|
-
}
|
|
252
|
-
|
|
253
139
|
declare global {
|
|
254
140
|
interface HTMLElementTagNameMap {
|
|
255
141
|
'roxy-vedic-kundli': RoxyVedicKundli;
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
import { css, html, LitElement, nothing } from 'lit';
|
|
2
|
+
import { customElement, property, state } from 'lit/decorators.js';
|
|
3
|
+
import type { GetYogaResponse, ListYogasResponse } from '../types/index.js';
|
|
4
|
+
import { baseStyles } from '../utils/base-styles.js';
|
|
5
|
+
import { debounce } from '../utils/debounce.js';
|
|
6
|
+
|
|
7
|
+
type YogaListData =
|
|
8
|
+
| ListYogasResponse
|
|
9
|
+
| GetYogaResponse
|
|
10
|
+
| { yogas: Array<GetYogaResponse> };
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Yoga catalog and detail renderer. Accepts three data modes:
|
|
14
|
+
* - Catalog: ListYogasResponse (yogas array of {id, name} + total)
|
|
15
|
+
* - Detail: GetYogaResponse (single yoga with description, result, quality)
|
|
16
|
+
* - Detail array: { yogas: Array<GetYogaResponse> } for pre-filtered sets
|
|
17
|
+
*
|
|
18
|
+
* Catalog and detail-array modes include a live search filter.
|
|
19
|
+
*/
|
|
20
|
+
@customElement('roxy-yoga-list')
|
|
21
|
+
export class RoxyYogaList extends LitElement {
|
|
22
|
+
static styles = [
|
|
23
|
+
baseStyles,
|
|
24
|
+
css`
|
|
25
|
+
.wrap {
|
|
26
|
+
display: grid;
|
|
27
|
+
gap: var(--roxy-space-md, 1rem);
|
|
28
|
+
}
|
|
29
|
+
.head {
|
|
30
|
+
display: flex;
|
|
31
|
+
justify-content: space-between;
|
|
32
|
+
align-items: baseline;
|
|
33
|
+
flex-wrap: wrap;
|
|
34
|
+
gap: var(--roxy-space-sm, 0.5rem);
|
|
35
|
+
}
|
|
36
|
+
.title {
|
|
37
|
+
font-size: var(--roxy-text-lg, 1.125rem);
|
|
38
|
+
font-weight: var(--roxy-weight-bold, 600);
|
|
39
|
+
margin: 0;
|
|
40
|
+
}
|
|
41
|
+
.count {
|
|
42
|
+
font-size: var(--roxy-text-sm, 0.875rem);
|
|
43
|
+
color: var(--roxy-muted, #71717a);
|
|
44
|
+
}
|
|
45
|
+
.search-wrap {
|
|
46
|
+
display: flex;
|
|
47
|
+
align-items: center;
|
|
48
|
+
gap: var(--roxy-space-sm, 0.5rem);
|
|
49
|
+
}
|
|
50
|
+
.search {
|
|
51
|
+
width: 100%;
|
|
52
|
+
max-width: 280px;
|
|
53
|
+
padding: 0.35em 0.75em;
|
|
54
|
+
font-size: var(--roxy-text-sm, 0.875rem);
|
|
55
|
+
font-family: var(--roxy-font-sans);
|
|
56
|
+
border: 1px solid var(--roxy-border, #e4e4e7);
|
|
57
|
+
border-radius: var(--roxy-radius-md, 8px);
|
|
58
|
+
background: var(--roxy-bg, #fff);
|
|
59
|
+
color: var(--roxy-fg, #0a0a0a);
|
|
60
|
+
outline: none;
|
|
61
|
+
}
|
|
62
|
+
.search::placeholder {
|
|
63
|
+
color: var(--roxy-fg, #0a0a0a);
|
|
64
|
+
opacity: 0.65;
|
|
65
|
+
}
|
|
66
|
+
.search:focus {
|
|
67
|
+
border-color: var(--roxy-accent, #f59e0b);
|
|
68
|
+
box-shadow: 0 0 0 2px color-mix(in srgb, var(--roxy-accent, #f59e0b) 30%, transparent);
|
|
69
|
+
}
|
|
70
|
+
.grid {
|
|
71
|
+
display: grid;
|
|
72
|
+
gap: var(--roxy-space-sm, 0.5rem);
|
|
73
|
+
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
|
|
74
|
+
}
|
|
75
|
+
.yoga-chip {
|
|
76
|
+
padding: 0.4em 0.8em;
|
|
77
|
+
border: 1px solid var(--roxy-border, #e4e4e7);
|
|
78
|
+
border-radius: var(--roxy-radius-md, 8px);
|
|
79
|
+
font-size: var(--roxy-text-sm, 0.875rem);
|
|
80
|
+
background: var(--roxy-bg, #fff);
|
|
81
|
+
color: var(--roxy-fg, #0a0a0a);
|
|
82
|
+
word-break: break-word;
|
|
83
|
+
}
|
|
84
|
+
.yoga-chip .yoga-id {
|
|
85
|
+
display: block;
|
|
86
|
+
font-size: 0.7em;
|
|
87
|
+
color: var(--roxy-fg, #0a0a0a);
|
|
88
|
+
opacity: 0.75;
|
|
89
|
+
margin-top: 0.15em;
|
|
90
|
+
}
|
|
91
|
+
.detail-card {
|
|
92
|
+
border: 1px solid var(--roxy-border, #e4e4e7);
|
|
93
|
+
border-radius: var(--roxy-radius-md, 8px);
|
|
94
|
+
padding: var(--roxy-space-md, 1rem);
|
|
95
|
+
background: var(--roxy-bg, #fff);
|
|
96
|
+
display: grid;
|
|
97
|
+
gap: var(--roxy-space-sm, 0.5rem);
|
|
98
|
+
}
|
|
99
|
+
.detail-name {
|
|
100
|
+
font-size: var(--roxy-text-lg, 1.125rem);
|
|
101
|
+
font-weight: var(--roxy-weight-bold, 600);
|
|
102
|
+
margin: 0;
|
|
103
|
+
display: flex;
|
|
104
|
+
align-items: center;
|
|
105
|
+
gap: var(--roxy-space-sm, 0.5rem);
|
|
106
|
+
flex-wrap: wrap;
|
|
107
|
+
}
|
|
108
|
+
.quality-chip {
|
|
109
|
+
display: inline-block;
|
|
110
|
+
font-size: var(--roxy-text-xs, 0.75rem);
|
|
111
|
+
font-weight: 600;
|
|
112
|
+
padding: 0.15em 0.6em;
|
|
113
|
+
border-radius: 999px;
|
|
114
|
+
}
|
|
115
|
+
.quality-Positive {
|
|
116
|
+
background: color-mix(in srgb, var(--roxy-success, #22c55e) 18%, transparent);
|
|
117
|
+
color: var(--roxy-success-fg, #15803d);
|
|
118
|
+
border: 1px solid color-mix(in srgb, var(--roxy-success, #22c55e) 40%, transparent);
|
|
119
|
+
}
|
|
120
|
+
.quality-Negative {
|
|
121
|
+
background: color-mix(in srgb, var(--roxy-danger, #ef4444) 18%, transparent);
|
|
122
|
+
color: var(--roxy-danger-fg, #b91c1c);
|
|
123
|
+
border: 1px solid color-mix(in srgb, var(--roxy-danger, #ef4444) 40%, transparent);
|
|
124
|
+
}
|
|
125
|
+
.quality-Both {
|
|
126
|
+
background: color-mix(in srgb, var(--roxy-warning, #f59e0b) 18%, transparent);
|
|
127
|
+
color: var(--roxy-warning-fg, #b45309);
|
|
128
|
+
border: 1px solid color-mix(in srgb, var(--roxy-warning, #f59e0b) 40%, transparent);
|
|
129
|
+
}
|
|
130
|
+
.description {
|
|
131
|
+
font-size: var(--roxy-text-sm, 0.875rem);
|
|
132
|
+
color: var(--roxy-muted, #71717a);
|
|
133
|
+
margin: 0;
|
|
134
|
+
line-height: var(--roxy-leading-normal, 1.5);
|
|
135
|
+
}
|
|
136
|
+
details {
|
|
137
|
+
font-size: var(--roxy-text-sm, 0.875rem);
|
|
138
|
+
}
|
|
139
|
+
details summary {
|
|
140
|
+
cursor: pointer;
|
|
141
|
+
color: var(--roxy-accent-fg, #b45309);
|
|
142
|
+
font-weight: 500;
|
|
143
|
+
padding: 0.25em 0;
|
|
144
|
+
list-style: none;
|
|
145
|
+
display: flex;
|
|
146
|
+
align-items: center;
|
|
147
|
+
gap: 0.4em;
|
|
148
|
+
}
|
|
149
|
+
details summary::before {
|
|
150
|
+
content: '+';
|
|
151
|
+
font-size: 1.1em;
|
|
152
|
+
line-height: 1;
|
|
153
|
+
}
|
|
154
|
+
details[open] summary::before {
|
|
155
|
+
content: '-';
|
|
156
|
+
}
|
|
157
|
+
details .result-body {
|
|
158
|
+
padding-top: var(--roxy-space-xs, 0.25rem);
|
|
159
|
+
color: var(--roxy-fg, #0a0a0a);
|
|
160
|
+
line-height: var(--roxy-leading-normal, 1.5);
|
|
161
|
+
}
|
|
162
|
+
.no-results {
|
|
163
|
+
color: var(--roxy-muted, #71717a);
|
|
164
|
+
font-size: var(--roxy-text-sm, 0.875rem);
|
|
165
|
+
padding: var(--roxy-space-md, 1rem) 0;
|
|
166
|
+
text-align: center;
|
|
167
|
+
}
|
|
168
|
+
.detail-grid {
|
|
169
|
+
display: grid;
|
|
170
|
+
gap: var(--roxy-space-sm, 0.5rem);
|
|
171
|
+
}
|
|
172
|
+
`,
|
|
173
|
+
];
|
|
174
|
+
|
|
175
|
+
@property({ attribute: false })
|
|
176
|
+
data: YogaListData | null = null;
|
|
177
|
+
|
|
178
|
+
@state()
|
|
179
|
+
private filter = '';
|
|
180
|
+
|
|
181
|
+
private readonly handleInput = debounce((e: Event) => {
|
|
182
|
+
this.filter = (e.target as HTMLInputElement).value;
|
|
183
|
+
}, 200);
|
|
184
|
+
|
|
185
|
+
private renderQualityChip(quality: string) {
|
|
186
|
+
const cls = `quality-chip quality-${quality}`;
|
|
187
|
+
return html`<span class=${cls}>${quality}</span>`;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
private renderDetailCard(yoga: GetYogaResponse) {
|
|
191
|
+
return html`<div class="detail-card">
|
|
192
|
+
<p class="detail-name">
|
|
193
|
+
${yoga.name}
|
|
194
|
+
${yoga.quality ? this.renderQualityChip(yoga.quality) : nothing}
|
|
195
|
+
</p>
|
|
196
|
+
${
|
|
197
|
+
yoga.description
|
|
198
|
+
? html`<p class="description">${yoga.description}</p>`
|
|
199
|
+
: nothing
|
|
200
|
+
}
|
|
201
|
+
${
|
|
202
|
+
yoga.result
|
|
203
|
+
? html`<details>
|
|
204
|
+
<summary>Effects</summary>
|
|
205
|
+
<div class="result-body">${yoga.result}</div>
|
|
206
|
+
</details>`
|
|
207
|
+
: nothing
|
|
208
|
+
}
|
|
209
|
+
</div>`;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
render() {
|
|
213
|
+
if (!this.data)
|
|
214
|
+
return html`<div class="roxy-empty" role="status">No yoga data</div>`;
|
|
215
|
+
|
|
216
|
+
const d = this.data;
|
|
217
|
+
const lc = this.filter.toLowerCase();
|
|
218
|
+
|
|
219
|
+
// Detail mode: single GetYogaResponse
|
|
220
|
+
if (
|
|
221
|
+
'description' in d &&
|
|
222
|
+
typeof (d as GetYogaResponse).description === 'string'
|
|
223
|
+
) {
|
|
224
|
+
const yoga = d as GetYogaResponse;
|
|
225
|
+
return html`<div class="wrap">${this.renderDetailCard(yoga)}</div>`;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Detail-array mode: { yogas: Array<GetYogaResponse> } where items have description
|
|
229
|
+
if ('yogas' in d && Array.isArray((d as { yogas: unknown[] }).yogas)) {
|
|
230
|
+
const allYogas = (
|
|
231
|
+
d as { yogas: Array<GetYogaResponse | { id: string; name: string }> }
|
|
232
|
+
).yogas;
|
|
233
|
+
const isDetailArray = allYogas.length > 0 && 'description' in allYogas[0];
|
|
234
|
+
|
|
235
|
+
if (isDetailArray) {
|
|
236
|
+
const detailYogas = allYogas as GetYogaResponse[];
|
|
237
|
+
const filtered = lc
|
|
238
|
+
? detailYogas.filter((y) => y.name.toLowerCase().includes(lc))
|
|
239
|
+
: detailYogas;
|
|
240
|
+
const total = (d as ListYogasResponse).total;
|
|
241
|
+
return html`<div class="wrap">
|
|
242
|
+
<div class="head">
|
|
243
|
+
<h2 class="title">Yoga catalog</h2>
|
|
244
|
+
${
|
|
245
|
+
total !== undefined
|
|
246
|
+
? html`<span class="count">${total} total</span>`
|
|
247
|
+
: nothing
|
|
248
|
+
}
|
|
249
|
+
</div>
|
|
250
|
+
<div class="search-wrap">
|
|
251
|
+
<input
|
|
252
|
+
class="search"
|
|
253
|
+
type="search"
|
|
254
|
+
placeholder="Filter yogas..."
|
|
255
|
+
aria-label="Filter yoga list by name"
|
|
256
|
+
.value=${this.filter}
|
|
257
|
+
@input=${this.handleInput}
|
|
258
|
+
/>
|
|
259
|
+
</div>
|
|
260
|
+
<div
|
|
261
|
+
class="detail-grid"
|
|
262
|
+
role="region"
|
|
263
|
+
aria-live="polite"
|
|
264
|
+
aria-label="Yoga results"
|
|
265
|
+
>
|
|
266
|
+
${
|
|
267
|
+
filtered.length > 0
|
|
268
|
+
? filtered.map((y) => this.renderDetailCard(y))
|
|
269
|
+
: html`<p class="no-results">No yogas match your search.</p>`
|
|
270
|
+
}
|
|
271
|
+
</div>
|
|
272
|
+
</div>`;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Catalog mode: ListYogasResponse with {id, name} items
|
|
276
|
+
const catalogYogas = allYogas as Array<{ id: string; name: string }>;
|
|
277
|
+
const filtered = lc
|
|
278
|
+
? catalogYogas.filter((y) => y.name.toLowerCase().includes(lc))
|
|
279
|
+
: catalogYogas;
|
|
280
|
+
const total = (d as ListYogasResponse).total;
|
|
281
|
+
return html`<div class="wrap">
|
|
282
|
+
<div class="head">
|
|
283
|
+
<h2 class="title">Yoga catalog</h2>
|
|
284
|
+
${
|
|
285
|
+
total !== undefined
|
|
286
|
+
? html`<span class="count">${total} total</span>`
|
|
287
|
+
: nothing
|
|
288
|
+
}
|
|
289
|
+
</div>
|
|
290
|
+
<div class="search-wrap">
|
|
291
|
+
<input
|
|
292
|
+
class="search"
|
|
293
|
+
type="search"
|
|
294
|
+
placeholder="Filter yogas..."
|
|
295
|
+
aria-label="Filter yoga list by name"
|
|
296
|
+
.value=${this.filter}
|
|
297
|
+
@input=${this.handleInput}
|
|
298
|
+
/>
|
|
299
|
+
</div>
|
|
300
|
+
<div
|
|
301
|
+
class="grid"
|
|
302
|
+
role="region"
|
|
303
|
+
aria-live="polite"
|
|
304
|
+
aria-label="Yoga results"
|
|
305
|
+
>
|
|
306
|
+
${
|
|
307
|
+
filtered.length > 0
|
|
308
|
+
? filtered.map(
|
|
309
|
+
(y) => html`<div class="yoga-chip">
|
|
310
|
+
${y.name}
|
|
311
|
+
<span class="yoga-id">${y.id}</span>
|
|
312
|
+
</div>`,
|
|
313
|
+
)
|
|
314
|
+
: html`<p class="no-results">No yogas match your search.</p>`
|
|
315
|
+
}
|
|
316
|
+
</div>
|
|
317
|
+
</div>`;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return html`<div class="roxy-empty" role="status">No yoga data</div>`;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
declare global {
|
|
325
|
+
interface HTMLElementTagNameMap {
|
|
326
|
+
'roxy-yoga-list': RoxyYogaList;
|
|
327
|
+
}
|
|
328
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -5,12 +5,15 @@
|
|
|
5
5
|
* import '@roxyapi/ui/components/natal-chart';
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
export { RoxyAshtakavargaGrid } from './components/ashtakavarga-grid.js';
|
|
8
9
|
// Biorhythm
|
|
9
10
|
export { RoxyBiorhythmChart } from './components/biorhythm-chart.js';
|
|
11
|
+
export { RoxyChoghadiyaGrid } from './components/choghadiya-grid.js';
|
|
10
12
|
export { RoxyCompatibilityCard } from './components/compatibility-card.js';
|
|
11
13
|
export { RoxyDashaTimeline } from './components/dasha-timeline.js';
|
|
12
14
|
// Generic fallback first so it is always available for nested rendering
|
|
13
15
|
export { RoxyData } from './components/data.js';
|
|
16
|
+
export { RoxyDivisionalChart } from './components/divisional-chart.js';
|
|
14
17
|
export { RoxyDoshaCard } from './components/dosha-card.js';
|
|
15
18
|
// Helpers
|
|
16
19
|
export { RoxyEndpointForm } from './components/endpoint-form.js';
|
|
@@ -21,41 +24,30 @@ export { RoxyHoroscopeCard } from './components/horoscope-card.js';
|
|
|
21
24
|
export { RoxyKpPlanetsTable } from './components/kp-planets-table.js';
|
|
22
25
|
export { RoxyLocationSearch } from './components/location-search.js';
|
|
23
26
|
export { RoxyMoonPhase } from './components/moon-phase.js';
|
|
24
|
-
// Western
|
|
27
|
+
// Western astrology
|
|
25
28
|
export { RoxyNatalChart } from './components/natal-chart.js';
|
|
26
29
|
// Numerology
|
|
27
30
|
export { RoxyNumerologyCard } from './components/numerology-card.js';
|
|
28
31
|
export { RoxyPanchangTable } from './components/panchang-table.js';
|
|
32
|
+
export { RoxyShadbalaTable } from './components/shadbala-table.js';
|
|
29
33
|
export { RoxySynastryChart } from './components/synastry-chart.js';
|
|
30
34
|
// Tarot
|
|
31
35
|
export { RoxyTarotCard } from './components/tarot-card.js';
|
|
32
36
|
export { RoxyTarotSpread } from './components/tarot-spread.js';
|
|
33
|
-
|
|
37
|
+
export { RoxyTransitsTable } from './components/transits-table.js';
|
|
38
|
+
// Vedic astrology
|
|
34
39
|
export { RoxyVedicKundli } from './components/vedic-kundli.js';
|
|
40
|
+
export { RoxyYogaList } from './components/yoga-list.js';
|
|
35
41
|
|
|
36
|
-
|
|
42
|
+
import { ROXY_COMPONENTS, type RoxyComponentSlug } from './manifest.js';
|
|
37
43
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
'moon-phase',
|
|
45
|
-
'vedic-kundli',
|
|
46
|
-
'panchang-table',
|
|
47
|
-
'dasha-timeline',
|
|
48
|
-
'dosha-card',
|
|
49
|
-
'guna-milan',
|
|
50
|
-
'kp-planets-table',
|
|
51
|
-
'numerology-card',
|
|
52
|
-
'tarot-card',
|
|
53
|
-
'tarot-spread',
|
|
54
|
-
'biorhythm-chart',
|
|
55
|
-
'hexagram',
|
|
56
|
-
'endpoint-form',
|
|
57
|
-
'location-search',
|
|
58
|
-
'data',
|
|
59
|
-
] as const;
|
|
44
|
+
export {
|
|
45
|
+
ROXY_COMPONENTS,
|
|
46
|
+
type RoxyComponent,
|
|
47
|
+
type RoxyComponentSlug,
|
|
48
|
+
} from './manifest.js';
|
|
49
|
+
export { ROXY_UI_VERSION } from './version.js';
|
|
60
50
|
|
|
61
|
-
|
|
51
|
+
/** Slugs in declaration order. Kept for the auto-mount widgets script and downstream codegen. */
|
|
52
|
+
export const ROXY_UI_COMPONENTS: readonly RoxyComponentSlug[] =
|
|
53
|
+
ROXY_COMPONENTS.map((c) => c.slug) as RoxyComponentSlug[];
|