@roxyapi/ui 0.8.1 → 0.10.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 +54 -13
- package/README.md +33 -22
- package/THEMING.md +7 -5
- package/dist/cdn/components/angel-number-card.js +45 -0
- package/dist/cdn/components/angel-number-card.js.map +7 -0
- package/dist/cdn/components/angel-number-lookup.js +45 -0
- package/dist/cdn/components/angel-number-lookup.js.map +7 -0
- package/dist/cdn/components/ashtakavarga-grid.js +3 -3
- package/dist/cdn/components/ashtakavarga-grid.js.map +3 -3
- package/dist/cdn/components/biorhythm-chart.js +3 -3
- package/dist/cdn/components/biorhythm-chart.js.map +3 -3
- package/dist/cdn/components/bodygraph.js +8 -8
- package/dist/cdn/components/bodygraph.js.map +3 -3
- package/dist/cdn/components/choghadiya-grid.js +3 -3
- package/dist/cdn/components/choghadiya-grid.js.map +3 -3
- package/dist/cdn/components/compatibility-card.js +2 -2
- package/dist/cdn/components/compatibility-card.js.map +3 -3
- package/dist/cdn/components/crystal-grid.js +45 -0
- package/dist/cdn/components/crystal-grid.js.map +7 -0
- package/dist/cdn/components/dasha-timeline.js +2 -2
- package/dist/cdn/components/dasha-timeline.js.map +3 -3
- package/dist/cdn/components/data.js +2 -2
- package/dist/cdn/components/data.js.map +3 -3
- package/dist/cdn/components/divisional-chart.js +7 -7
- package/dist/cdn/components/divisional-chart.js.map +3 -3
- package/dist/cdn/components/dosha-card.js +3 -3
- package/dist/cdn/components/dosha-card.js.map +3 -3
- package/dist/cdn/components/dream-card.js +45 -0
- package/dist/cdn/components/dream-card.js.map +7 -0
- package/dist/cdn/components/forecast-timeline.js +3 -3
- package/dist/cdn/components/forecast-timeline.js.map +3 -3
- package/dist/cdn/components/guna-milan.js +3 -3
- package/dist/cdn/components/guna-milan.js.map +3 -3
- package/dist/cdn/components/hexagram.js +2 -2
- package/dist/cdn/components/hexagram.js.map +3 -3
- package/dist/cdn/components/horoscope-card.js +3 -3
- package/dist/cdn/components/horoscope-card.js.map +3 -3
- package/dist/cdn/components/kp-chart.js +2 -2
- package/dist/cdn/components/kp-chart.js.map +3 -3
- package/dist/cdn/components/kp-planets-table.js +3 -3
- package/dist/cdn/components/kp-planets-table.js.map +3 -3
- package/dist/cdn/components/kp-ruling-planets.js +3 -3
- package/dist/cdn/components/kp-ruling-planets.js.map +3 -3
- package/dist/cdn/components/moon-phase.js +3 -3
- package/dist/cdn/components/moon-phase.js.map +3 -3
- package/dist/cdn/components/nakshatra-card.js +3 -3
- package/dist/cdn/components/nakshatra-card.js.map +3 -3
- package/dist/cdn/components/natal-chart.js +2 -2
- package/dist/cdn/components/natal-chart.js.map +3 -3
- package/dist/cdn/components/numerology-card.js +3 -3
- package/dist/cdn/components/numerology-card.js.map +3 -3
- package/dist/cdn/components/panchang-table.js +2 -2
- package/dist/cdn/components/panchang-table.js.map +3 -3
- package/dist/cdn/components/shadbala-table.js +3 -3
- package/dist/cdn/components/shadbala-table.js.map +3 -3
- package/dist/cdn/components/synastry-chart.js +5 -5
- package/dist/cdn/components/synastry-chart.js.map +3 -3
- package/dist/cdn/components/tarot-card.js.map +3 -3
- package/dist/cdn/components/tarot-spread.js +3 -3
- package/dist/cdn/components/tarot-spread.js.map +3 -3
- package/dist/cdn/components/transits-table.js +3 -3
- package/dist/cdn/components/transits-table.js.map +3 -3
- package/dist/cdn/components/vedic-kundli.js +16 -16
- package/dist/cdn/components/vedic-kundli.js.map +3 -3
- package/dist/cdn/components/vedic-planets-table.js +3 -3
- package/dist/cdn/components/vedic-planets-table.js.map +3 -3
- package/dist/cdn/components/western-planets-table.js +2 -2
- package/dist/cdn/components/western-planets-table.js.map +3 -3
- package/dist/cdn/components/yoga-list.js +2 -2
- package/dist/cdn/components/yoga-list.js.map +3 -3
- package/dist/cdn/roxy-ui.js +289 -66
- 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/components/angel-number-card.d.ts +18 -0
- package/dist/components/angel-number-card.d.ts.map +1 -0
- package/dist/components/angel-number-card.js +2 -0
- package/dist/components/angel-number-card.js.map +7 -0
- package/dist/components/angel-number-lookup.d.ts +18 -0
- package/dist/components/angel-number-lookup.d.ts.map +1 -0
- package/dist/components/angel-number-lookup.js +2 -0
- package/dist/components/angel-number-lookup.js.map +7 -0
- package/dist/components/ashtakavarga-grid.js +1 -1
- package/dist/components/ashtakavarga-grid.js.map +3 -3
- package/dist/components/biorhythm-chart.js +1 -1
- package/dist/components/biorhythm-chart.js.map +3 -3
- package/dist/components/bodygraph.js +4 -4
- package/dist/components/bodygraph.js.map +3 -3
- package/dist/components/choghadiya-grid.js +1 -1
- package/dist/components/choghadiya-grid.js.map +3 -3
- package/dist/components/compatibility-card.js +1 -1
- package/dist/components/compatibility-card.js.map +3 -3
- package/dist/components/crystal-grid.d.ts +27 -0
- package/dist/components/crystal-grid.d.ts.map +1 -0
- package/dist/components/crystal-grid.js +2 -0
- package/dist/components/crystal-grid.js.map +7 -0
- package/dist/components/dasha-timeline.js +1 -1
- package/dist/components/dasha-timeline.js.map +3 -3
- package/dist/components/data.js +1 -1
- package/dist/components/data.js.map +3 -3
- package/dist/components/divisional-chart.js +34 -34
- package/dist/components/divisional-chart.js.map +3 -3
- package/dist/components/dosha-card.js +1 -1
- package/dist/components/dosha-card.js.map +3 -3
- package/dist/components/dream-card.d.ts +17 -0
- package/dist/components/dream-card.d.ts.map +1 -0
- package/dist/components/dream-card.js +2 -0
- package/dist/components/dream-card.js.map +7 -0
- package/dist/components/forecast-timeline.js.map +3 -3
- package/dist/components/guna-milan.js +1 -1
- package/dist/components/guna-milan.js.map +3 -3
- package/dist/components/hexagram.js +1 -1
- package/dist/components/hexagram.js.map +3 -3
- package/dist/components/horoscope-card.js +1 -1
- package/dist/components/horoscope-card.js.map +3 -3
- package/dist/components/kp-chart.js +1 -1
- package/dist/components/kp-chart.js.map +3 -3
- package/dist/components/kp-planets-table.js +1 -1
- package/dist/components/kp-planets-table.js.map +3 -3
- package/dist/components/kp-ruling-planets.js +1 -1
- package/dist/components/kp-ruling-planets.js.map +3 -3
- package/dist/components/moon-phase.js +1 -1
- package/dist/components/moon-phase.js.map +3 -3
- package/dist/components/nakshatra-card.js +1 -1
- package/dist/components/nakshatra-card.js.map +3 -3
- package/dist/components/natal-chart.js +5 -5
- package/dist/components/natal-chart.js.map +3 -3
- package/dist/components/numerology-card.d.ts +7 -3
- package/dist/components/numerology-card.d.ts.map +1 -1
- package/dist/components/numerology-card.js +1 -1
- package/dist/components/numerology-card.js.map +3 -3
- package/dist/components/panchang-table.js +1 -1
- package/dist/components/panchang-table.js.map +3 -3
- package/dist/components/shadbala-table.js +1 -1
- package/dist/components/shadbala-table.js.map +3 -3
- package/dist/components/synastry-chart.js +4 -4
- package/dist/components/synastry-chart.js.map +3 -3
- package/dist/components/tarot-card.js +1 -1
- package/dist/components/tarot-card.js.map +3 -3
- package/dist/components/tarot-spread.js +1 -1
- package/dist/components/tarot-spread.js.map +3 -3
- package/dist/components/transits-table.js +1 -1
- package/dist/components/transits-table.js.map +3 -3
- package/dist/components/vedic-kundli.d.ts +18 -0
- package/dist/components/vedic-kundli.d.ts.map +1 -1
- package/dist/components/vedic-kundli.js +62 -62
- package/dist/components/vedic-kundli.js.map +3 -3
- package/dist/components/vedic-planets-table.js +1 -1
- package/dist/components/vedic-planets-table.js.map +3 -3
- package/dist/components/western-planets-table.js +1 -1
- package/dist/components/western-planets-table.js.map +3 -3
- package/dist/components/yoga-list.js +1 -1
- package/dist/components/yoga-list.js.map +3 -3
- package/dist/index.cjs +74 -74
- 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 +74 -74
- package/dist/index.js.map +4 -4
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.json +28 -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/utils/kundli-render.d.ts +2 -1
- package/dist/utils/kundli-render.d.ts.map +1 -1
- package/dist/utils/markup-data.d.ts +34 -0
- package/dist/utils/markup-data.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/cdn.ts +15 -0
- package/src/components/angel-number-card.ts +234 -0
- package/src/components/angel-number-lookup.ts +208 -0
- package/src/components/crystal-grid.ts +191 -0
- package/src/components/dream-card.ts +98 -0
- package/src/components/numerology-card.ts +22 -10
- package/src/components/vedic-kundli.ts +37 -2
- package/src/index.ts +14 -0
- package/src/manifest.ts +57 -5
- 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/utils/kundli-render.ts +9 -2
- package/src/utils/markup-data.ts +45 -0
- package/src/version.ts +1 -1
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { css, html, LitElement, nothing } from 'lit';
|
|
2
|
+
import { customElement, property } from 'lit/decorators.js';
|
|
3
|
+
import type {
|
|
4
|
+
GetBirthstonesResponse,
|
|
5
|
+
GetCrystalsByChakraResponse,
|
|
6
|
+
GetCrystalsByElementResponse,
|
|
7
|
+
GetCrystalsByZodiacResponse,
|
|
8
|
+
ListCrystalsResponse,
|
|
9
|
+
SearchCrystalsResponse,
|
|
10
|
+
} from '../types/index.js';
|
|
11
|
+
import { baseStyles } from '../utils/base-styles.js';
|
|
12
|
+
import { MarkupDataController } from '../utils/markup-data.js';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Any crystal list response that carries a `crystals` summary array. Every crystals endpoint that returns more than one stone shares the `{ name, id, imageUrl, colors }` item shape, so one grid renders them all.
|
|
16
|
+
*/
|
|
17
|
+
type CrystalGridData =
|
|
18
|
+
| ListCrystalsResponse
|
|
19
|
+
| GetCrystalsByChakraResponse
|
|
20
|
+
| GetCrystalsByElementResponse
|
|
21
|
+
| GetCrystalsByZodiacResponse
|
|
22
|
+
| GetBirthstonesResponse
|
|
23
|
+
| SearchCrystalsResponse;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Month number to birthstone month name for the derived heading.
|
|
27
|
+
*/
|
|
28
|
+
const MONTHS = [
|
|
29
|
+
'January',
|
|
30
|
+
'February',
|
|
31
|
+
'March',
|
|
32
|
+
'April',
|
|
33
|
+
'May',
|
|
34
|
+
'June',
|
|
35
|
+
'July',
|
|
36
|
+
'August',
|
|
37
|
+
'September',
|
|
38
|
+
'October',
|
|
39
|
+
'November',
|
|
40
|
+
'December',
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Crystal grid. Renders any crystals list response (/crystals, /crystals/chakra/{chakra}, /crystals/element/{element}, /crystals/zodiac/{sign}, /crystals/birthstone/{month}, /crystals/search) as a responsive gallery of crystal tiles with photo, name, and colour swatches. The heading is derived from the response filter (chakra, element, zodiac sign, or birth month) or set explicitly via the `heading` attribute.
|
|
45
|
+
*/
|
|
46
|
+
@customElement('roxy-crystal-grid')
|
|
47
|
+
export class RoxyCrystalGrid extends LitElement {
|
|
48
|
+
static styles = [
|
|
49
|
+
baseStyles,
|
|
50
|
+
css`
|
|
51
|
+
.wrap {
|
|
52
|
+
display: grid;
|
|
53
|
+
gap: var(--roxy-space-md, 1rem);
|
|
54
|
+
}
|
|
55
|
+
.head {
|
|
56
|
+
display: flex;
|
|
57
|
+
align-items: baseline;
|
|
58
|
+
justify-content: space-between;
|
|
59
|
+
gap: var(--roxy-space-sm, 0.5rem);
|
|
60
|
+
flex-wrap: wrap;
|
|
61
|
+
}
|
|
62
|
+
.title {
|
|
63
|
+
margin: 0;
|
|
64
|
+
font-size: var(--roxy-text-lg, 1.125rem);
|
|
65
|
+
font-weight: var(--roxy-weight-bold, 600);
|
|
66
|
+
color: var(--roxy-fg, #0a0a0a);
|
|
67
|
+
}
|
|
68
|
+
.count {
|
|
69
|
+
color: var(--roxy-muted, #71717a);
|
|
70
|
+
font-size: var(--roxy-text-sm, 0.875rem);
|
|
71
|
+
}
|
|
72
|
+
.grid {
|
|
73
|
+
display: grid;
|
|
74
|
+
grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr));
|
|
75
|
+
gap: var(--roxy-space-md, 1rem);
|
|
76
|
+
margin: 0;
|
|
77
|
+
padding: 0;
|
|
78
|
+
list-style: none;
|
|
79
|
+
}
|
|
80
|
+
.tile {
|
|
81
|
+
display: grid;
|
|
82
|
+
gap: var(--roxy-space-xs, 0.25rem);
|
|
83
|
+
background: var(--roxy-bg, #fff);
|
|
84
|
+
border: 1px solid var(--roxy-border, #e4e4e7);
|
|
85
|
+
border-radius: var(--roxy-radius-md, 8px);
|
|
86
|
+
padding: var(--roxy-space-sm, 0.5rem);
|
|
87
|
+
box-shadow: var(--roxy-shadow-sm);
|
|
88
|
+
}
|
|
89
|
+
.photo {
|
|
90
|
+
aspect-ratio: 1 / 1;
|
|
91
|
+
width: 100%;
|
|
92
|
+
border-radius: var(--roxy-radius-sm, 4px);
|
|
93
|
+
object-fit: cover;
|
|
94
|
+
background: color-mix(in srgb, var(--roxy-border, #e4e4e7) 35%, transparent);
|
|
95
|
+
}
|
|
96
|
+
.name {
|
|
97
|
+
margin: 0;
|
|
98
|
+
font-size: var(--roxy-text-sm, 0.875rem);
|
|
99
|
+
font-weight: var(--roxy-weight-bold, 600);
|
|
100
|
+
color: var(--roxy-fg, #0a0a0a);
|
|
101
|
+
}
|
|
102
|
+
.colors {
|
|
103
|
+
display: flex;
|
|
104
|
+
flex-wrap: wrap;
|
|
105
|
+
gap: 4px;
|
|
106
|
+
}
|
|
107
|
+
.swatch {
|
|
108
|
+
width: 10px;
|
|
109
|
+
height: 10px;
|
|
110
|
+
border-radius: var(--roxy-radius-full, 9999px);
|
|
111
|
+
border: 1px solid color-mix(in srgb, var(--roxy-fg, #0a0a0a) 18%, transparent);
|
|
112
|
+
}
|
|
113
|
+
`,
|
|
114
|
+
];
|
|
115
|
+
|
|
116
|
+
constructor() {
|
|
117
|
+
super();
|
|
118
|
+
// Enables hydrating `data` from a direct-child
|
|
119
|
+
// <script type="application/json" class="roxy-data"> for server-rendered
|
|
120
|
+
// and cached consumers. The JavaScript `data` property still wins.
|
|
121
|
+
new MarkupDataController(this);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
@property({ attribute: false })
|
|
125
|
+
data: CrystalGridData | null = null;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Override the auto-derived grid heading. Empty by default, in which case the heading comes from the response filter (chakra, element, zodiac, or birth month) or falls back to "Crystals".
|
|
129
|
+
*/
|
|
130
|
+
@property({ type: String, reflect: true })
|
|
131
|
+
heading = '';
|
|
132
|
+
|
|
133
|
+
render() {
|
|
134
|
+
const d = this.data;
|
|
135
|
+
const crystals = d?.crystals ?? [];
|
|
136
|
+
if (!d || crystals.length === 0)
|
|
137
|
+
return html`<div class="roxy-empty" role="status">No crystals</div>`;
|
|
138
|
+
|
|
139
|
+
const title = this.heading || this.deriveHeading(d);
|
|
140
|
+
const total =
|
|
141
|
+
'total' in d && typeof d.total === 'number' ? d.total : crystals.length;
|
|
142
|
+
|
|
143
|
+
return html`<section class="wrap" aria-label=${title}>
|
|
144
|
+
<header class="head">
|
|
145
|
+
<h2 class="title">${title}</h2>
|
|
146
|
+
<span class="count">${total} ${total === 1 ? 'crystal' : 'crystals'}</span>
|
|
147
|
+
</header>
|
|
148
|
+
<ul class="grid">
|
|
149
|
+
${crystals.map(
|
|
150
|
+
(c) => html`<li class="tile">
|
|
151
|
+
${
|
|
152
|
+
c.imageUrl
|
|
153
|
+
? html`<img class="photo" src=${c.imageUrl} alt=${c.name ?? 'Crystal'} loading="lazy" />`
|
|
154
|
+
: html`<div class="photo" aria-hidden="true"></div>`
|
|
155
|
+
}
|
|
156
|
+
<p class="name">${c.name}</p>
|
|
157
|
+
${
|
|
158
|
+
c.colors && c.colors.length > 0
|
|
159
|
+
? html`<div class="colors" aria-label=${`Colours: ${c.colors.join(', ')}`}>
|
|
160
|
+
${c.colors.map((col) => html`<span class="swatch" style=${`background:${cssColor(col)}`} title=${col}></span>`)}
|
|
161
|
+
</div>`
|
|
162
|
+
: nothing
|
|
163
|
+
}
|
|
164
|
+
</li>`,
|
|
165
|
+
)}
|
|
166
|
+
</ul>
|
|
167
|
+
</section>`;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
private deriveHeading(d: CrystalGridData): string {
|
|
171
|
+
if ('chakra' in d && d.chakra) return `${d.chakra} chakra crystals`;
|
|
172
|
+
if ('element' in d && d.element) return `${d.element} element crystals`;
|
|
173
|
+
if ('sign' in d && d.sign) return `Crystals for ${d.sign}`;
|
|
174
|
+
if ('month' in d && typeof d.month === 'number')
|
|
175
|
+
return `${MONTHS[d.month - 1] ?? ''} birthstones`.trim();
|
|
176
|
+
return 'Crystals';
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Map an API colour keyword to a CSS colour. Most crystal colours (violet, purple, green, blue) are valid CSS named colours; multi-word or non-standard values (blue-green, lavender) fall back to the keyword and, if the browser cannot resolve it, the swatch border still renders. Lower-cased and space-stripped so "Blue Green" resolves to the CSS hyphen form where it exists.
|
|
182
|
+
*/
|
|
183
|
+
function cssColor(name: string): string {
|
|
184
|
+
return name.trim().toLowerCase().replace(/\s+/g, '');
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
declare global {
|
|
188
|
+
interface HTMLElementTagNameMap {
|
|
189
|
+
'roxy-crystal-grid': RoxyCrystalGrid;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { css, html, LitElement, nothing } from 'lit';
|
|
2
|
+
import { customElement, property } from 'lit/decorators.js';
|
|
3
|
+
import type { GetDreamSymbolResponse } from '../types/index.js';
|
|
4
|
+
import { baseStyles } from '../utils/base-styles.js';
|
|
5
|
+
import { MarkupDataController } from '../utils/markup-data.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Dream symbol card. Renders /dreams/symbols/{id}: the symbol name as a heading, the full psychological interpretation as the body, and the dictionary letter as a chip for alphabetical context.
|
|
9
|
+
*/
|
|
10
|
+
@customElement('roxy-dream-card')
|
|
11
|
+
export class RoxyDreamCard extends LitElement {
|
|
12
|
+
static styles = [
|
|
13
|
+
baseStyles,
|
|
14
|
+
css`
|
|
15
|
+
.card {
|
|
16
|
+
background: var(--roxy-bg, #fff);
|
|
17
|
+
border: 1px solid var(--roxy-border, #e4e4e7);
|
|
18
|
+
border-radius: var(--roxy-radius-md, 8px);
|
|
19
|
+
padding: var(--roxy-space-lg, 1.5rem);
|
|
20
|
+
box-shadow: var(--roxy-shadow-sm);
|
|
21
|
+
display: grid;
|
|
22
|
+
gap: var(--roxy-space-md, 1rem);
|
|
23
|
+
}
|
|
24
|
+
.head {
|
|
25
|
+
display: flex;
|
|
26
|
+
align-items: center;
|
|
27
|
+
gap: var(--roxy-space-md, 1rem);
|
|
28
|
+
}
|
|
29
|
+
.letter {
|
|
30
|
+
display: inline-flex;
|
|
31
|
+
align-items: center;
|
|
32
|
+
justify-content: center;
|
|
33
|
+
width: 2.5rem;
|
|
34
|
+
height: 2.5rem;
|
|
35
|
+
flex: none;
|
|
36
|
+
border-radius: var(--roxy-radius-full, 9999px);
|
|
37
|
+
background: color-mix(in srgb, var(--roxy-accent, #f59e0b) 16%, transparent);
|
|
38
|
+
color: var(--roxy-accent-ink, #b45309);
|
|
39
|
+
font-size: var(--roxy-text-lg, 1.125rem);
|
|
40
|
+
font-weight: var(--roxy-weight-bold, 600);
|
|
41
|
+
text-transform: uppercase;
|
|
42
|
+
font-variant-numeric: tabular-nums;
|
|
43
|
+
}
|
|
44
|
+
.label {
|
|
45
|
+
margin: 0;
|
|
46
|
+
font-size: var(--roxy-text-xs, 0.75rem);
|
|
47
|
+
color: var(--roxy-muted, #71717a);
|
|
48
|
+
text-transform: uppercase;
|
|
49
|
+
letter-spacing: 0.06em;
|
|
50
|
+
}
|
|
51
|
+
.name {
|
|
52
|
+
margin: 0;
|
|
53
|
+
font-size: var(--roxy-text-lg, 1.125rem);
|
|
54
|
+
font-weight: var(--roxy-weight-bold, 600);
|
|
55
|
+
color: var(--roxy-fg, #0a0a0a);
|
|
56
|
+
}
|
|
57
|
+
.meaning {
|
|
58
|
+
margin: 0;
|
|
59
|
+
color: var(--roxy-fg, #0a0a0a);
|
|
60
|
+
line-height: 1.6;
|
|
61
|
+
}
|
|
62
|
+
`,
|
|
63
|
+
];
|
|
64
|
+
|
|
65
|
+
constructor() {
|
|
66
|
+
super();
|
|
67
|
+
// Enables hydrating `data` from a direct-child
|
|
68
|
+
// <script type="application/json" class="roxy-data"> for server-rendered
|
|
69
|
+
// and cached consumers. The JavaScript `data` property still wins.
|
|
70
|
+
new MarkupDataController(this);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@property({ attribute: false })
|
|
74
|
+
data: GetDreamSymbolResponse | null = null;
|
|
75
|
+
|
|
76
|
+
render() {
|
|
77
|
+
const d = this.data;
|
|
78
|
+
if (!d)
|
|
79
|
+
return html`<div class="roxy-empty" role="status">No dream symbol</div>`;
|
|
80
|
+
|
|
81
|
+
return html`<article class="card" aria-label=${d.name ?? 'Dream symbol'}>
|
|
82
|
+
<header class="head">
|
|
83
|
+
${d.letter ? html`<span class="letter" aria-hidden="true">${d.letter}</span>` : nothing}
|
|
84
|
+
<div>
|
|
85
|
+
<p class="label">Dream symbol</p>
|
|
86
|
+
${d.name ? html`<h2 class="name">${d.name}</h2>` : nothing}
|
|
87
|
+
</div>
|
|
88
|
+
</header>
|
|
89
|
+
${d.meaning ? html`<p class="meaning">${d.meaning}</p>` : nothing}
|
|
90
|
+
</article>`;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
declare global {
|
|
95
|
+
interface HTMLElementTagNameMap {
|
|
96
|
+
'roxy-dream-card': RoxyDreamCard;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -3,16 +3,26 @@ import { customElement, property } from 'lit/decorators.js';
|
|
|
3
3
|
import type {
|
|
4
4
|
CalculateExpressionResponse,
|
|
5
5
|
CalculateLifePathResponse,
|
|
6
|
+
CalculatePersonalityResponse,
|
|
6
7
|
CalculatePersonalYearResponse,
|
|
8
|
+
CalculateSoulUrgeResponse,
|
|
7
9
|
GenerateNumerologyChartResponse,
|
|
8
10
|
} from '../types/index.js';
|
|
9
11
|
import { baseStyles } from '../utils/base-styles.js';
|
|
10
12
|
import { MarkupDataController } from '../utils/markup-data.js';
|
|
11
13
|
import { humanize } from '../utils/string.js';
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Single-number numerology responses that share the number + meaning + calculation + karmic-debt shape. {@link RoxyNumerologyCard.renderNumberCard} renders any of them; the `type` attribute selects only the heading label.
|
|
17
|
+
*/
|
|
18
|
+
type NumberCardData =
|
|
14
19
|
| CalculateLifePathResponse
|
|
15
20
|
| CalculateExpressionResponse
|
|
21
|
+
| CalculateSoulUrgeResponse
|
|
22
|
+
| CalculatePersonalityResponse;
|
|
23
|
+
|
|
24
|
+
type NumerologyData =
|
|
25
|
+
| NumberCardData
|
|
16
26
|
| CalculatePersonalYearResponse
|
|
17
27
|
| GenerateNumerologyChartResponse;
|
|
18
28
|
|
|
@@ -135,7 +145,13 @@ export class RoxyNumerologyCard extends LitElement {
|
|
|
135
145
|
data: NumerologyData | null = null;
|
|
136
146
|
|
|
137
147
|
@property({ type: String, reflect: true })
|
|
138
|
-
type:
|
|
148
|
+
type:
|
|
149
|
+
| 'life-path'
|
|
150
|
+
| 'expression'
|
|
151
|
+
| 'soul-urge'
|
|
152
|
+
| 'personality'
|
|
153
|
+
| 'personal-year'
|
|
154
|
+
| 'chart' = 'life-path';
|
|
139
155
|
|
|
140
156
|
render() {
|
|
141
157
|
const d = this.data;
|
|
@@ -146,16 +162,10 @@ export class RoxyNumerologyCard extends LitElement {
|
|
|
146
162
|
|
|
147
163
|
if ('coreNumbers' in d) return this.renderChart(d, headerLabel);
|
|
148
164
|
if ('personalYear' in d) return this.renderPersonalYear(d, headerLabel);
|
|
149
|
-
return this.renderNumberCard(
|
|
150
|
-
d as CalculateLifePathResponse | CalculateExpressionResponse,
|
|
151
|
-
headerLabel,
|
|
152
|
-
);
|
|
165
|
+
return this.renderNumberCard(d as NumberCardData, headerLabel);
|
|
153
166
|
}
|
|
154
167
|
|
|
155
|
-
private renderNumberCard(
|
|
156
|
-
d: CalculateLifePathResponse | CalculateExpressionResponse,
|
|
157
|
-
headerLabel: string,
|
|
158
|
-
) {
|
|
168
|
+
private renderNumberCard(d: NumberCardData, headerLabel: string) {
|
|
159
169
|
const keywords = d.meaning?.keywords ?? [];
|
|
160
170
|
return html`<article class="card" aria-label=${headerLabel}>
|
|
161
171
|
<div class="hero">
|
|
@@ -230,6 +240,8 @@ export class RoxyNumerologyCard extends LitElement {
|
|
|
230
240
|
const LABELS: Record<string, string> = {
|
|
231
241
|
'life-path': 'Life Path',
|
|
232
242
|
expression: 'Expression',
|
|
243
|
+
'soul-urge': 'Soul Urge',
|
|
244
|
+
personality: 'Personality',
|
|
233
245
|
'personal-year': 'Personal Year',
|
|
234
246
|
chart: 'Numerology chart',
|
|
235
247
|
};
|
|
@@ -24,6 +24,12 @@ import { tablistStyles } from '../utils/tablist.js';
|
|
|
24
24
|
* page sets the initial style via `chart-style` attribute; from there the
|
|
25
25
|
* user takes over.
|
|
26
26
|
*
|
|
27
|
+
* The ascendant (house 1) defaults to the Janma Lagna carried in the response
|
|
28
|
+
* `meta`. Set `chart-reference="moon"` to render the Chandra Lagna (Moon as
|
|
29
|
+
* ascendant) from the same response, or `lagna-override="<rashi>"` to pin the
|
|
30
|
+
* reference to any sign (Surya Lagna, Arudha Lagna, a custom point). The same
|
|
31
|
+
* planet-in-sign data feeds every reference; only the house numbering rotates.
|
|
32
|
+
*
|
|
27
33
|
* Theming flows through CSS custom properties on `:host`, so the chart
|
|
28
34
|
* adopts the host page palette without runtime color probing.
|
|
29
35
|
*/
|
|
@@ -45,9 +51,34 @@ export class RoxyVedicKundli extends LitElement {
|
|
|
45
51
|
@property({ type: String, reflect: true, attribute: 'chart-style' })
|
|
46
52
|
chartStyle: ChartStyle = 'north';
|
|
47
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Ascendant reference point. `'lagna'` (default) uses the Janma Lagna from the response; `'moon'` renders the Chandra Lagna (Moon sign as house 1) from the same response. An explicit {@link lagnaOverride} wins over this.
|
|
56
|
+
*/
|
|
57
|
+
@property({ type: String, reflect: true, attribute: 'chart-reference' })
|
|
58
|
+
chartReference: 'lagna' | 'moon' = 'lagna';
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Explicit rashi/sign name (case-insensitive, e.g. `"cancer"`) to use as the ascendant, overriding both the Janma Lagna and {@link chartReference}. Empty by default (standard Janma Lagna). Use for Surya Lagna, Arudha Lagna, or any custom reference chart.
|
|
62
|
+
*/
|
|
63
|
+
@property({ type: String, reflect: true, attribute: 'lagna-override' })
|
|
64
|
+
lagnaOverride = '';
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Resolve the ascendant override fed to {@link toKundliViewModel}. An explicit `lagna-override` wins; otherwise `chart-reference="moon"` derives the Moon rashi from the response `meta`. Returns `undefined` for the default Janma Lagna path.
|
|
68
|
+
*/
|
|
69
|
+
private resolveReference(): string | undefined {
|
|
70
|
+
if (this.lagnaOverride) return this.lagnaOverride;
|
|
71
|
+
if (this.chartReference === 'moon') return this.data?.meta?.Moon?.rashi;
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
|
|
48
75
|
private viewModel(): KundliViewModel | null {
|
|
49
76
|
if (!this.data?.meta) return null;
|
|
50
|
-
return toKundliViewModel(
|
|
77
|
+
return toKundliViewModel(
|
|
78
|
+
this.data.meta,
|
|
79
|
+
'D1 Rashi',
|
|
80
|
+
this.resolveReference(),
|
|
81
|
+
);
|
|
51
82
|
}
|
|
52
83
|
|
|
53
84
|
private setStyle = (next: ChartStyle) => {
|
|
@@ -58,9 +89,13 @@ export class RoxyVedicKundli extends LitElement {
|
|
|
58
89
|
const vm = this.viewModel();
|
|
59
90
|
if (!vm)
|
|
60
91
|
return html`<div class="roxy-empty" role="status">No kundli data</div>`;
|
|
92
|
+
const title =
|
|
93
|
+
this.chartReference === 'moon' && !this.lagnaOverride
|
|
94
|
+
? 'Chandra lagna'
|
|
95
|
+
: 'Vedic kundli';
|
|
61
96
|
return html`<div class="wrap">
|
|
62
97
|
<div class="header">
|
|
63
|
-
<h2 class="title"
|
|
98
|
+
<h2 class="title">${title}</h2>
|
|
64
99
|
${renderKundliStyleTablist(this.chartStyle, this.setStyle)}
|
|
65
100
|
</div>
|
|
66
101
|
<svg
|
package/src/index.ts
CHANGED
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
* import '@roxyapi/ui/components/natal-chart';
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
// Angel numbers
|
|
9
|
+
export { RoxyAngelNumberCard } from './components/angel-number-card.js';
|
|
10
|
+
export { RoxyAngelNumberLookup } from './components/angel-number-lookup.js';
|
|
8
11
|
export { RoxyAshtakavargaGrid } from './components/ashtakavarga-grid.js';
|
|
9
12
|
// Biorhythm
|
|
10
13
|
export { RoxyBiorhythmChart } from './components/biorhythm-chart.js';
|
|
@@ -12,11 +15,15 @@ export { RoxyBiorhythmChart } from './components/biorhythm-chart.js';
|
|
|
12
15
|
export { RoxyBodygraph } from './components/bodygraph.js';
|
|
13
16
|
export { RoxyChoghadiyaGrid } from './components/choghadiya-grid.js';
|
|
14
17
|
export { RoxyCompatibilityCard } from './components/compatibility-card.js';
|
|
18
|
+
// Crystals
|
|
19
|
+
export { RoxyCrystalGrid } from './components/crystal-grid.js';
|
|
15
20
|
export { RoxyDashaTimeline } from './components/dasha-timeline.js';
|
|
16
21
|
// Generic fallback first so it is always available for nested rendering
|
|
17
22
|
export { RoxyData } from './components/data.js';
|
|
18
23
|
export { RoxyDivisionalChart } from './components/divisional-chart.js';
|
|
19
24
|
export { RoxyDoshaCard } from './components/dosha-card.js';
|
|
25
|
+
// Dreams
|
|
26
|
+
export { RoxyDreamCard } from './components/dream-card.js';
|
|
20
27
|
// Helpers
|
|
21
28
|
export { RoxyEndpointForm } from './components/endpoint-form.js';
|
|
22
29
|
// Forecast
|
|
@@ -48,6 +55,13 @@ export { RoxyVedicPlanetsTable } from './components/vedic-planets-table.js';
|
|
|
48
55
|
export { RoxyWesternPlanetsTable } from './components/western-planets-table.js';
|
|
49
56
|
export { RoxyYogaList } from './components/yoga-list.js';
|
|
50
57
|
|
|
58
|
+
// SSR helpers for the server-rendered hydration path (Pattern 7). Safe writers
|
|
59
|
+
// for the inline <script class="roxy-data"> the MarkupDataController reads.
|
|
60
|
+
export {
|
|
61
|
+
roxyDataScript,
|
|
62
|
+
serializeRoxyData,
|
|
63
|
+
} from './utils/markup-data.js';
|
|
64
|
+
|
|
51
65
|
import { ROXY_COMPONENTS, type RoxyComponentSlug } from './manifest.js';
|
|
52
66
|
|
|
53
67
|
export {
|
package/src/manifest.ts
CHANGED
|
@@ -130,10 +130,11 @@ export const ROXY_COMPONENTS: readonly RoxyComponent[] = [
|
|
|
130
130
|
slug: 'vedic-kundli',
|
|
131
131
|
heading: 'Vedic kundli',
|
|
132
132
|
description:
|
|
133
|
-
'South, North, or East Indian Vedic kundli for /vedic-astrology/birth-chart with per-planet degree and nakshatra detail',
|
|
133
|
+
'South, North, or East Indian Vedic kundli for /vedic-astrology/birth-chart with per-planet degree and nakshatra detail, plus an optional Chandra Lagna (Moon-as-ascendant) reference view',
|
|
134
134
|
docsLabel: 'Vedic',
|
|
135
135
|
endpointLabel: 'POST /vedic-astrology/birth-chart',
|
|
136
|
-
docsSummary:
|
|
136
|
+
docsSummary:
|
|
137
|
+
'South, North, or East Indian kundli with degree detail and optional Chandra Lagna view',
|
|
137
138
|
topic: 'Vedic',
|
|
138
139
|
},
|
|
139
140
|
{
|
|
@@ -305,11 +306,12 @@ export const ROXY_COMPONENTS: readonly RoxyComponent[] = [
|
|
|
305
306
|
slug: 'numerology-card',
|
|
306
307
|
heading: 'Life path number',
|
|
307
308
|
description:
|
|
308
|
-
'Numerology card for life path, expression, personal year, or full chart',
|
|
309
|
+
'Numerology card for life path, expression, soul urge, personality, personal year, or full chart',
|
|
309
310
|
docsLabel: 'Numerology',
|
|
310
311
|
endpointLabel:
|
|
311
|
-
'POST /numerology/{life-path,expression,personal-year,chart}',
|
|
312
|
-
docsSummary:
|
|
312
|
+
'POST /numerology/{life-path,expression,soul-urge,personality,personal-year,chart}',
|
|
313
|
+
docsSummary:
|
|
314
|
+
'Life path, expression, soul urge, personality, personal year, full chart',
|
|
313
315
|
topic: 'Numerology',
|
|
314
316
|
},
|
|
315
317
|
{
|
|
@@ -386,6 +388,56 @@ export const ROXY_COMPONENTS: readonly RoxyComponent[] = [
|
|
|
386
388
|
docsSummary: 'Hexagram with trigrams, judgment, image, changing lines',
|
|
387
389
|
topic: 'I Ching',
|
|
388
390
|
},
|
|
391
|
+
{
|
|
392
|
+
pascal: 'RoxyCrystalGrid',
|
|
393
|
+
tag: 'roxy-crystal-grid',
|
|
394
|
+
slug: 'crystal-grid',
|
|
395
|
+
heading: 'Crystal grid',
|
|
396
|
+
description:
|
|
397
|
+
'Responsive crystal gallery with photo, name, and colour swatches from any crystals list response',
|
|
398
|
+
docsLabel: 'Crystals',
|
|
399
|
+
endpointLabel:
|
|
400
|
+
'GET /crystals, /crystals/chakra/{chakra}, /crystals/element/{element}, /crystals/zodiac/{sign}, /crystals/birthstone/{month}, /crystals/search',
|
|
401
|
+
docsSummary: 'Crystal gallery tiles with photo, name, and colour swatches',
|
|
402
|
+
topic: 'Crystals',
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
pascal: 'RoxyDreamCard',
|
|
406
|
+
tag: 'roxy-dream-card',
|
|
407
|
+
slug: 'dream-card',
|
|
408
|
+
heading: 'Dream symbol',
|
|
409
|
+
description:
|
|
410
|
+
'Dream symbol card with the symbol name, full interpretation, and dictionary letter',
|
|
411
|
+
docsLabel: 'Dreams',
|
|
412
|
+
endpointLabel: 'GET /dreams/symbols/{id}',
|
|
413
|
+
docsSummary: 'Symbol name, interpretation body, and letter chip',
|
|
414
|
+
topic: 'Dreams',
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
pascal: 'RoxyAngelNumberCard',
|
|
418
|
+
tag: 'roxy-angel-number-card',
|
|
419
|
+
slug: 'angel-number-card',
|
|
420
|
+
heading: 'Angel number',
|
|
421
|
+
description:
|
|
422
|
+
'Angel number card with title, core message, badges, keywords, life-area interpretations, affirmation, and action steps',
|
|
423
|
+
docsLabel: 'Angel Numbers',
|
|
424
|
+
endpointLabel: 'GET /angel-numbers/numbers/{number}',
|
|
425
|
+
docsSummary:
|
|
426
|
+
'Number meaning with spiritual, love, career, and twin flame sections',
|
|
427
|
+
topic: 'Angel Numbers',
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
pascal: 'RoxyAngelNumberLookup',
|
|
431
|
+
tag: 'roxy-angel-number-lookup',
|
|
432
|
+
slug: 'angel-number-lookup',
|
|
433
|
+
heading: 'Angel number lookup',
|
|
434
|
+
description:
|
|
435
|
+
'Angel number sequence analysis with pattern classification, the known meaning when present, and a digit-root fallback for any number',
|
|
436
|
+
docsLabel: 'Angel Numbers',
|
|
437
|
+
endpointLabel: 'GET /angel-numbers/lookup',
|
|
438
|
+
docsSummary: 'Pattern analysis plus known meaning and digit-root fallback',
|
|
439
|
+
topic: 'Angel Numbers',
|
|
440
|
+
},
|
|
389
441
|
{
|
|
390
442
|
pascal: 'RoxyEndpointForm',
|
|
391
443
|
tag: 'roxy-endpoint-form',
|