@roxyapi/ui 0.9.0 → 0.11.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 +53 -27
- package/README.md +42 -12
- package/components-catalog.json +1022 -0
- package/dist/cdn/components/angel-number-card.js +52 -0
- package/dist/cdn/components/angel-number-card.js.map +7 -0
- package/dist/cdn/components/angel-number-lookup.js +52 -0
- package/dist/cdn/components/angel-number-lookup.js.map +7 -0
- package/dist/cdn/components/ashtakavarga-grid.js +10 -3
- package/dist/cdn/components/ashtakavarga-grid.js.map +4 -4
- package/dist/cdn/components/aspects-table.js +52 -0
- package/dist/cdn/components/aspects-table.js.map +7 -0
- package/dist/cdn/components/biorhythm-chart.js +10 -3
- package/dist/cdn/components/biorhythm-chart.js.map +4 -4
- package/dist/cdn/components/bodygraph.js +17 -10
- package/dist/cdn/components/bodygraph.js.map +4 -4
- package/dist/cdn/components/choghadiya-grid.js +10 -3
- package/dist/cdn/components/choghadiya-grid.js.map +4 -4
- package/dist/cdn/components/compatibility-card.js +10 -3
- package/dist/cdn/components/compatibility-card.js.map +4 -4
- package/dist/cdn/components/crystal-card.js +52 -0
- package/dist/cdn/components/crystal-card.js.map +7 -0
- package/dist/cdn/components/crystal-grid.js +52 -0
- package/dist/cdn/components/crystal-grid.js.map +7 -0
- package/dist/cdn/components/dasha-timeline.js +10 -3
- package/dist/cdn/components/dasha-timeline.js.map +4 -4
- package/dist/cdn/components/data.js +10 -3
- package/dist/cdn/components/data.js.map +4 -4
- package/dist/cdn/components/divisional-chart.js +31 -24
- package/dist/cdn/components/divisional-chart.js.map +4 -4
- package/dist/cdn/components/dosha-card.js +10 -3
- package/dist/cdn/components/dosha-card.js.map +4 -4
- package/dist/cdn/components/dream-card.js +52 -0
- package/dist/cdn/components/dream-card.js.map +7 -0
- package/dist/cdn/components/dream-search.js +52 -0
- package/dist/cdn/components/dream-search.js.map +7 -0
- package/dist/cdn/components/endpoint-form.js +3 -3
- package/dist/cdn/components/endpoint-form.js.map +3 -3
- package/dist/cdn/components/forecast-digest.js +52 -0
- package/dist/cdn/components/forecast-digest.js.map +7 -0
- package/dist/cdn/components/forecast-timeline.js +10 -3
- package/dist/cdn/components/forecast-timeline.js.map +4 -4
- package/dist/cdn/components/guna-milan.js +10 -3
- package/dist/cdn/components/guna-milan.js.map +4 -4
- package/dist/cdn/components/hd-connection.js +52 -0
- package/dist/cdn/components/hd-connection.js.map +7 -0
- package/dist/cdn/components/hd-penta.js +52 -0
- package/dist/cdn/components/hd-penta.js.map +7 -0
- package/dist/cdn/components/hd-variables.js +52 -0
- package/dist/cdn/components/hd-variables.js.map +7 -0
- package/dist/cdn/components/hexagram.js +10 -3
- package/dist/cdn/components/hexagram.js.map +4 -4
- package/dist/cdn/components/hora-table.js +52 -0
- package/dist/cdn/components/hora-table.js.map +7 -0
- package/dist/cdn/components/horoscope-card.js +10 -3
- package/dist/cdn/components/horoscope-card.js.map +4 -4
- package/dist/cdn/components/kp-chart.js +10 -3
- package/dist/cdn/components/kp-chart.js.map +4 -4
- package/dist/cdn/components/kp-planets-table.js +10 -3
- package/dist/cdn/components/kp-planets-table.js.map +4 -4
- package/dist/cdn/components/kp-ruling-planets.js +10 -3
- package/dist/cdn/components/kp-ruling-planets.js.map +4 -4
- package/dist/cdn/components/location-search.js +3 -3
- package/dist/cdn/components/location-search.js.map +2 -2
- package/dist/cdn/components/moon-phase.js +10 -3
- package/dist/cdn/components/moon-phase.js.map +4 -4
- package/dist/cdn/components/nakshatra-card.js +10 -3
- package/dist/cdn/components/nakshatra-card.js.map +4 -4
- package/dist/cdn/components/natal-chart.js +16 -9
- package/dist/cdn/components/natal-chart.js.map +4 -4
- package/dist/cdn/components/numerology-card.js +10 -3
- package/dist/cdn/components/numerology-card.js.map +4 -4
- package/dist/cdn/components/panchang-table.js +10 -3
- package/dist/cdn/components/panchang-table.js.map +4 -4
- package/dist/cdn/components/reference-card.js +52 -0
- package/dist/cdn/components/reference-card.js.map +7 -0
- package/dist/cdn/components/shadbala-table.js +10 -3
- package/dist/cdn/components/shadbala-table.js.map +4 -4
- package/dist/cdn/components/synastry-chart.js +16 -9
- package/dist/cdn/components/synastry-chart.js.map +4 -4
- package/dist/cdn/components/tarot-card.js +10 -3
- package/dist/cdn/components/tarot-card.js.map +4 -4
- package/dist/cdn/components/tarot-catalog.js +52 -0
- package/dist/cdn/components/tarot-catalog.js.map +7 -0
- package/dist/cdn/components/tarot-spread.js +10 -3
- package/dist/cdn/components/tarot-spread.js.map +4 -4
- package/dist/cdn/components/transits-table.js +10 -3
- package/dist/cdn/components/transits-table.js.map +4 -4
- package/dist/cdn/components/vedic-aspects.js +52 -0
- package/dist/cdn/components/vedic-aspects.js.map +7 -0
- package/dist/cdn/components/vedic-kundli.js +31 -24
- package/dist/cdn/components/vedic-kundli.js.map +4 -4
- package/dist/cdn/components/vedic-planets-table.js +10 -3
- package/dist/cdn/components/vedic-planets-table.js.map +4 -4
- package/dist/cdn/components/western-planets-table.js +10 -3
- package/dist/cdn/components/western-planets-table.js.map +4 -4
- package/dist/cdn/components/yoga-list.js +10 -3
- package/dist/cdn/components/yoga-list.js.map +4 -4
- package/dist/cdn/roxy-ui.js +92 -81
- package/dist/cdn/roxy-ui.js.map +4 -4
- package/dist/components/angel-number-card.d.ts +17 -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 +21 -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.d.ts +4 -5
- package/dist/components/ashtakavarga-grid.d.ts.map +1 -1
- package/dist/components/ashtakavarga-grid.js +1 -1
- package/dist/components/ashtakavarga-grid.js.map +4 -4
- package/dist/components/aspects-table.d.ts +23 -0
- package/dist/components/aspects-table.d.ts.map +1 -0
- package/dist/components/aspects-table.js +2 -0
- package/dist/components/aspects-table.js.map +7 -0
- package/dist/components/biorhythm-chart.d.ts +4 -5
- package/dist/components/biorhythm-chart.d.ts.map +1 -1
- package/dist/components/biorhythm-chart.js +1 -1
- package/dist/components/biorhythm-chart.js.map +4 -4
- package/dist/components/bodygraph.d.ts +4 -5
- package/dist/components/bodygraph.d.ts.map +1 -1
- package/dist/components/bodygraph.js +9 -9
- package/dist/components/bodygraph.js.map +4 -4
- package/dist/components/choghadiya-grid.d.ts +4 -5
- package/dist/components/choghadiya-grid.d.ts.map +1 -1
- package/dist/components/choghadiya-grid.js +1 -1
- package/dist/components/choghadiya-grid.js.map +4 -4
- package/dist/components/compatibility-card.d.ts +4 -5
- package/dist/components/compatibility-card.d.ts.map +1 -1
- package/dist/components/compatibility-card.js +1 -1
- package/dist/components/compatibility-card.js.map +4 -4
- package/dist/components/crystal-card.d.ts +19 -0
- package/dist/components/crystal-card.d.ts.map +1 -0
- package/dist/components/crystal-card.js +2 -0
- package/dist/components/crystal-card.js.map +7 -0
- package/dist/components/crystal-grid.d.ts +26 -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.d.ts +4 -5
- package/dist/components/dasha-timeline.d.ts.map +1 -1
- package/dist/components/dasha-timeline.js +1 -1
- package/dist/components/dasha-timeline.js.map +4 -4
- package/dist/components/data.d.ts +5 -8
- package/dist/components/data.d.ts.map +1 -1
- package/dist/components/data.js +1 -1
- package/dist/components/data.js.map +4 -4
- package/dist/components/divisional-chart.d.ts +4 -5
- package/dist/components/divisional-chart.d.ts.map +1 -1
- package/dist/components/divisional-chart.js +59 -59
- package/dist/components/divisional-chart.js.map +4 -4
- package/dist/components/dosha-card.d.ts +4 -5
- package/dist/components/dosha-card.d.ts.map +1 -1
- package/dist/components/dosha-card.js +1 -1
- package/dist/components/dosha-card.js.map +4 -4
- package/dist/components/dream-card.d.ts +16 -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/dream-search.d.ts +18 -0
- package/dist/components/dream-search.d.ts.map +1 -0
- package/dist/components/dream-search.js +2 -0
- package/dist/components/dream-search.js.map +7 -0
- package/dist/components/endpoint-form.d.ts +10 -5
- package/dist/components/endpoint-form.d.ts.map +1 -1
- package/dist/components/endpoint-form.js +1 -1
- package/dist/components/endpoint-form.js.map +3 -3
- package/dist/components/forecast-digest.d.ts +19 -0
- package/dist/components/forecast-digest.d.ts.map +1 -0
- package/dist/components/forecast-digest.js +2 -0
- package/dist/components/forecast-digest.js.map +7 -0
- package/dist/components/forecast-timeline.d.ts +8 -6
- package/dist/components/forecast-timeline.d.ts.map +1 -1
- package/dist/components/forecast-timeline.js +1 -1
- package/dist/components/forecast-timeline.js.map +4 -4
- package/dist/components/guna-milan.d.ts +4 -5
- package/dist/components/guna-milan.d.ts.map +1 -1
- package/dist/components/guna-milan.js +1 -1
- package/dist/components/guna-milan.js.map +4 -4
- package/dist/components/hd-connection.d.ts +18 -0
- package/dist/components/hd-connection.d.ts.map +1 -0
- package/dist/components/hd-connection.js +2 -0
- package/dist/components/hd-connection.js.map +7 -0
- package/dist/components/hd-penta.d.ts +18 -0
- package/dist/components/hd-penta.d.ts.map +1 -0
- package/dist/components/hd-penta.js +2 -0
- package/dist/components/hd-penta.js.map +7 -0
- package/dist/components/hd-variables.d.ts +17 -0
- package/dist/components/hd-variables.d.ts.map +1 -0
- package/dist/components/hd-variables.js +2 -0
- package/dist/components/hd-variables.js.map +7 -0
- package/dist/components/hexagram.d.ts +4 -5
- package/dist/components/hexagram.d.ts.map +1 -1
- package/dist/components/hexagram.js +1 -1
- package/dist/components/hexagram.js.map +4 -4
- package/dist/components/hora-table.d.ts +17 -0
- package/dist/components/hora-table.d.ts.map +1 -0
- package/dist/components/hora-table.js +2 -0
- package/dist/components/hora-table.js.map +7 -0
- package/dist/components/horoscope-card.d.ts +4 -5
- package/dist/components/horoscope-card.d.ts.map +1 -1
- package/dist/components/horoscope-card.js +1 -1
- package/dist/components/horoscope-card.js.map +4 -4
- package/dist/components/kp-chart.d.ts +4 -5
- package/dist/components/kp-chart.d.ts.map +1 -1
- package/dist/components/kp-chart.js +1 -1
- package/dist/components/kp-chart.js.map +4 -4
- package/dist/components/kp-planets-table.d.ts +4 -5
- package/dist/components/kp-planets-table.d.ts.map +1 -1
- package/dist/components/kp-planets-table.js +1 -1
- package/dist/components/kp-planets-table.js.map +4 -4
- package/dist/components/kp-ruling-planets.d.ts +4 -5
- package/dist/components/kp-ruling-planets.d.ts.map +1 -1
- package/dist/components/kp-ruling-planets.js +1 -1
- package/dist/components/kp-ruling-planets.js.map +4 -4
- package/dist/components/location-search.js +1 -1
- package/dist/components/location-search.js.map +2 -2
- package/dist/components/moon-phase.d.ts +5 -5
- package/dist/components/moon-phase.d.ts.map +1 -1
- package/dist/components/moon-phase.js +1 -1
- package/dist/components/moon-phase.js.map +4 -4
- package/dist/components/nakshatra-card.d.ts +4 -5
- package/dist/components/nakshatra-card.d.ts.map +1 -1
- package/dist/components/nakshatra-card.js +1 -1
- package/dist/components/nakshatra-card.js.map +4 -4
- package/dist/components/natal-chart.d.ts +4 -5
- package/dist/components/natal-chart.d.ts.map +1 -1
- package/dist/components/natal-chart.js +8 -8
- package/dist/components/natal-chart.js.map +4 -4
- package/dist/components/numerology-card.d.ts +15 -10
- 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 +4 -4
- package/dist/components/panchang-table.d.ts +4 -5
- package/dist/components/panchang-table.d.ts.map +1 -1
- package/dist/components/panchang-table.js +1 -1
- package/dist/components/panchang-table.js.map +4 -4
- package/dist/components/reference-card.d.ts +19 -0
- package/dist/components/reference-card.d.ts.map +1 -0
- package/dist/components/reference-card.js +2 -0
- package/dist/components/reference-card.js.map +7 -0
- package/dist/components/shadbala-table.d.ts +4 -5
- package/dist/components/shadbala-table.d.ts.map +1 -1
- package/dist/components/shadbala-table.js +1 -1
- package/dist/components/shadbala-table.js.map +4 -4
- package/dist/components/synastry-chart.d.ts +4 -5
- package/dist/components/synastry-chart.d.ts.map +1 -1
- package/dist/components/synastry-chart.js +7 -7
- package/dist/components/synastry-chart.js.map +4 -4
- package/dist/components/tarot-card.d.ts +4 -5
- package/dist/components/tarot-card.d.ts.map +1 -1
- package/dist/components/tarot-card.js +1 -1
- package/dist/components/tarot-card.js.map +4 -4
- package/dist/components/tarot-catalog.d.ts +20 -0
- package/dist/components/tarot-catalog.d.ts.map +1 -0
- package/dist/components/tarot-catalog.js +2 -0
- package/dist/components/tarot-catalog.js.map +7 -0
- package/dist/components/tarot-spread.d.ts +7 -8
- package/dist/components/tarot-spread.d.ts.map +1 -1
- package/dist/components/tarot-spread.js +1 -1
- package/dist/components/tarot-spread.js.map +4 -4
- package/dist/components/transits-table.d.ts +4 -5
- package/dist/components/transits-table.d.ts.map +1 -1
- package/dist/components/transits-table.js +1 -1
- package/dist/components/transits-table.js.map +4 -4
- package/dist/components/vedic-aspects.d.ts +16 -0
- package/dist/components/vedic-aspects.d.ts.map +1 -0
- package/dist/components/vedic-aspects.js +2 -0
- package/dist/components/vedic-aspects.js.map +7 -0
- package/dist/components/vedic-kundli.d.ts +22 -5
- package/dist/components/vedic-kundli.d.ts.map +1 -1
- package/dist/components/vedic-kundli.js +63 -63
- package/dist/components/vedic-kundli.js.map +4 -4
- package/dist/components/vedic-planets-table.d.ts +4 -5
- package/dist/components/vedic-planets-table.d.ts.map +1 -1
- package/dist/components/vedic-planets-table.js +1 -1
- package/dist/components/vedic-planets-table.js.map +4 -4
- package/dist/components/western-planets-table.d.ts +4 -5
- package/dist/components/western-planets-table.d.ts.map +1 -1
- package/dist/components/western-planets-table.js +1 -1
- package/dist/components/western-planets-table.js.map +4 -4
- package/dist/components/yoga-list.d.ts +6 -7
- package/dist/components/yoga-list.d.ts.map +1 -1
- package/dist/components/yoga-list.js +1 -1
- package/dist/components/yoga-list.js.map +4 -4
- package/dist/generated/endpoint-bindings.d.ts +15 -0
- package/dist/generated/endpoint-bindings.d.ts.map +1 -0
- package/dist/index.cjs +73 -73
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +71 -71
- package/dist/index.js.map +4 -4
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.json +39 -24
- package/dist/styles/tokens-css.d.ts +1 -1
- package/dist/styles/tokens-css.d.ts.map +1 -1
- package/dist/styles/tokens.css +4 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/types.gen.d.ts +1103 -164
- package/dist/types/types.gen.d.ts.map +1 -1
- package/dist/utils/angel-sections.d.ts +14 -0
- package/dist/utils/angel-sections.d.ts.map +1 -0
- package/dist/utils/base-element.d.ts +73 -0
- package/dist/utils/base-element.d.ts.map +1 -0
- package/dist/utils/base-styles.d.ts.map +1 -1
- package/dist/utils/fetch-controller.d.ts +60 -0
- package/dist/utils/fetch-controller.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/kundli-styles.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 +2 -1
- package/src/components/angel-number-card.ts +210 -0
- package/src/components/angel-number-lookup.ts +207 -0
- package/src/components/ashtakavarga-grid.ts +15 -20
- package/src/components/aspects-table.ts +329 -0
- package/src/components/biorhythm-chart.ts +14 -18
- package/src/components/bodygraph.ts +9 -20
- package/src/components/choghadiya-grid.ts +15 -19
- package/src/components/compatibility-card.ts +9 -19
- package/src/components/crystal-card.ts +242 -0
- package/src/components/crystal-grid.ts +182 -0
- package/src/components/dasha-timeline.ts +9 -20
- package/src/components/data.ts +8 -27
- package/src/components/divisional-chart.ts +10 -18
- package/src/components/dosha-card.ts +8 -19
- package/src/components/dream-card.ts +88 -0
- package/src/components/dream-search.ts +135 -0
- package/src/components/endpoint-form.ts +149 -55
- package/src/components/forecast-digest.ts +213 -0
- package/src/components/forecast-timeline.ts +24 -19
- package/src/components/guna-milan.ts +8 -19
- package/src/components/hd-connection.ts +188 -0
- package/src/components/hd-penta.ts +165 -0
- package/src/components/hd-variables.ts +128 -0
- package/src/components/hexagram.ts +10 -18
- package/src/components/hora-table.ts +149 -0
- package/src/components/horoscope-card.ts +9 -19
- package/src/components/kp-chart.ts +11 -20
- package/src/components/kp-planets-table.ts +11 -20
- package/src/components/kp-ruling-planets.ts +8 -18
- package/src/components/moon-phase.ts +10 -19
- package/src/components/nakshatra-card.ts +11 -20
- package/src/components/natal-chart.ts +20 -23
- package/src/components/numerology-card.ts +90 -31
- package/src/components/panchang-table.ts +9 -19
- package/src/components/reference-card.ts +212 -0
- package/src/components/shadbala-table.ts +15 -18
- package/src/components/synastry-chart.ts +17 -20
- package/src/components/tarot-card.ts +9 -20
- package/src/components/tarot-catalog.ts +129 -0
- package/src/components/tarot-spread.ts +20 -21
- package/src/components/transits-table.ts +17 -20
- package/src/components/vedic-aspects.ts +188 -0
- package/src/components/vedic-kundli.ts +46 -19
- package/src/components/vedic-planets-table.ts +11 -19
- package/src/components/western-planets-table.ts +11 -19
- package/src/components/yoga-list.ts +17 -23
- package/src/generated/endpoint-bindings.ts +655 -0
- package/src/index.ts +27 -0
- package/src/manifest.ts +198 -6
- package/src/styles/tokens-css.ts +4 -0
- package/src/styles/tokens.css +4 -0
- package/src/types/index.ts +1 -1
- package/src/types/types.gen.ts +1123 -164
- package/src/utils/angel-sections.ts +38 -0
- package/src/utils/base-element.ts +183 -0
- package/src/utils/base-styles.ts +33 -0
- package/src/utils/fetch-controller.ts +166 -0
- package/src/utils/kundli-render.ts +9 -2
- package/src/utils/kundli-styles.ts +7 -1
- package/src/utils/markup-data.ts +45 -0
- package/src/version.ts +1 -1
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { css, html,
|
|
2
|
-
import { customElement
|
|
1
|
+
import { css, html, nothing } from 'lit';
|
|
2
|
+
import { customElement } from 'lit/decorators.js';
|
|
3
3
|
import { PLANET_GLYPH } from '../tokens/index.js';
|
|
4
4
|
import type { GenerateBodygraphResponse } from '../types/index.js';
|
|
5
|
+
import { RoxyDataElement } from '../utils/base-element.js';
|
|
5
6
|
import { baseStyles } from '../utils/base-styles.js';
|
|
6
7
|
import {
|
|
7
8
|
BODYGRAPH_VIEWBOX,
|
|
@@ -9,7 +10,6 @@ import {
|
|
|
9
10
|
channelKey,
|
|
10
11
|
renderBodygraphSvg,
|
|
11
12
|
} from '../utils/bodygraph-render.js';
|
|
12
|
-
import { MarkupDataController } from '../utils/markup-data.js';
|
|
13
13
|
import { capitalize } from '../utils/string.js';
|
|
14
14
|
|
|
15
15
|
type GateActivation = GenerateBodygraphResponse['gates'][number];
|
|
@@ -26,7 +26,7 @@ type GateActivation = GenerateBodygraphResponse['gates'][number];
|
|
|
26
26
|
* it adopts the host palette in light and dark without runtime color probing.
|
|
27
27
|
*/
|
|
28
28
|
@customElement('roxy-bodygraph')
|
|
29
|
-
export class RoxyBodygraph extends
|
|
29
|
+
export class RoxyBodygraph extends RoxyDataElement<GenerateBodygraphResponse> {
|
|
30
30
|
static styles = [
|
|
31
31
|
baseStyles,
|
|
32
32
|
css`
|
|
@@ -65,7 +65,7 @@ export class RoxyBodygraph extends LitElement {
|
|
|
65
65
|
svg {
|
|
66
66
|
display: block;
|
|
67
67
|
width: 100%;
|
|
68
|
-
max-width: 340px;
|
|
68
|
+
max-width: var(--roxy-chart-max-width, 340px);
|
|
69
69
|
height: auto;
|
|
70
70
|
margin: 0 auto;
|
|
71
71
|
}
|
|
@@ -165,7 +165,7 @@ export class RoxyBodygraph extends LitElement {
|
|
|
165
165
|
border: 1px solid var(--roxy-border, #e4e4e7);
|
|
166
166
|
border-radius: var(--roxy-radius-md, 8px);
|
|
167
167
|
padding: var(--roxy-space-sm, 0.5rem) var(--roxy-space-md, 1rem);
|
|
168
|
-
background: var(--roxy-
|
|
168
|
+
background: var(--roxy-surface, #fff);
|
|
169
169
|
}
|
|
170
170
|
.fact span {
|
|
171
171
|
display: block;
|
|
@@ -251,22 +251,11 @@ export class RoxyBodygraph extends LitElement {
|
|
|
251
251
|
`,
|
|
252
252
|
];
|
|
253
253
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
// Enables hydrating `data` from a direct-child
|
|
257
|
-
// <script type="application/json" class="roxy-data"> for server-rendered
|
|
258
|
-
// and cached consumers. The JavaScript `data` property still wins.
|
|
259
|
-
new MarkupDataController(this);
|
|
254
|
+
protected renderEmpty() {
|
|
255
|
+
return html`<div class="roxy-empty" role="status">No bodygraph data</div>`;
|
|
260
256
|
}
|
|
261
257
|
|
|
262
|
-
|
|
263
|
-
data: GenerateBodygraphResponse | null = null;
|
|
264
|
-
|
|
265
|
-
render() {
|
|
266
|
-
const d = this.data;
|
|
267
|
-
if (!d)
|
|
268
|
-
return html`<div class="roxy-empty" role="status">No bodygraph data</div>`;
|
|
269
|
-
|
|
258
|
+
protected renderData(d: GenerateBodygraphResponse) {
|
|
270
259
|
const definedCenters = new Set<BodygraphCenterId>(
|
|
271
260
|
(d.centers ?? [])
|
|
272
261
|
.filter((c) => c.defined)
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { css, html,
|
|
2
|
-
import { customElement
|
|
1
|
+
import { css, html, nothing } from 'lit';
|
|
2
|
+
import { customElement } from 'lit/decorators.js';
|
|
3
3
|
import { PLANET_GLYPH } from '../tokens/index.js';
|
|
4
4
|
import type { GetChoghadiyaResponse } from '../types/index.js';
|
|
5
|
+
import { RoxyDataElement } from '../utils/base-element.js';
|
|
5
6
|
import { baseStyles } from '../utils/base-styles.js';
|
|
6
|
-
import { MarkupDataController } from '../utils/markup-data.js';
|
|
7
7
|
import { capitalize } from '../utils/string.js';
|
|
8
8
|
|
|
9
9
|
type ChoghadiyaPeriod = GetChoghadiyaResponse['dayChoghadiya'][number];
|
|
@@ -28,11 +28,17 @@ function fmtTime(iso: string): string {
|
|
|
28
28
|
* Good periods are highlighted in green, Bad periods in red.
|
|
29
29
|
*/
|
|
30
30
|
@customElement('roxy-choghadiya-grid')
|
|
31
|
-
export class RoxyChoghadiyaGrid extends
|
|
31
|
+
export class RoxyChoghadiyaGrid extends RoxyDataElement<GetChoghadiyaResponse> {
|
|
32
32
|
static styles = [
|
|
33
33
|
baseStyles,
|
|
34
34
|
css`
|
|
35
35
|
.wrap {
|
|
36
|
+
background: var(--roxy-surface, #fff);
|
|
37
|
+
color: var(--roxy-fg, #0a0a0a);
|
|
38
|
+
border: 1px solid var(--roxy-border, #e4e4e7);
|
|
39
|
+
border-radius: var(--roxy-radius-md, 8px);
|
|
40
|
+
padding: var(--roxy-space-lg, 1.5rem);
|
|
41
|
+
box-shadow: var(--roxy-shadow-sm);
|
|
36
42
|
display: grid;
|
|
37
43
|
gap: var(--roxy-space-md, 1rem);
|
|
38
44
|
}
|
|
@@ -133,17 +139,6 @@ export class RoxyChoghadiyaGrid extends LitElement {
|
|
|
133
139
|
`,
|
|
134
140
|
];
|
|
135
141
|
|
|
136
|
-
constructor() {
|
|
137
|
-
super();
|
|
138
|
-
// Enables hydrating `data` from a direct-child
|
|
139
|
-
// <script type="application/json" class="roxy-data"> for server-rendered
|
|
140
|
-
// and cached consumers. The JavaScript `data` property still wins.
|
|
141
|
-
new MarkupDataController(this);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
@property({ attribute: false })
|
|
145
|
-
data: GetChoghadiyaResponse | null = null;
|
|
146
|
-
|
|
147
142
|
/**
|
|
148
143
|
* True when the current wall-clock time falls inside this period. Both
|
|
149
144
|
* `start` and `end` are ISO 8601 with timezone, so the comparison is
|
|
@@ -183,11 +178,12 @@ export class RoxyChoghadiyaGrid extends LitElement {
|
|
|
183
178
|
</div>`;
|
|
184
179
|
}
|
|
185
180
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
181
|
+
protected renderEmpty() {
|
|
182
|
+
return html`<div class="roxy-empty" role="status">No choghadiya data</div>`;
|
|
183
|
+
}
|
|
189
184
|
|
|
190
|
-
|
|
185
|
+
protected renderData(d: GetChoghadiyaResponse) {
|
|
186
|
+
const { date, dayChoghadiya, nightChoghadiya } = d;
|
|
191
187
|
|
|
192
188
|
return html`<div class="wrap">
|
|
193
189
|
<div class="header">
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { css, html,
|
|
1
|
+
import { css, html, nothing } from 'lit';
|
|
2
2
|
import { customElement, property } from 'lit/decorators.js';
|
|
3
3
|
import type {
|
|
4
4
|
CalculateBioCompatibilityResponse,
|
|
5
5
|
CalculateCompatibilityResponse,
|
|
6
6
|
CalculateNumCompatibilityResponse,
|
|
7
7
|
} from '../types/index.js';
|
|
8
|
+
import { RoxyDataElement } from '../utils/base-element.js';
|
|
8
9
|
import { baseStyles } from '../utils/base-styles.js';
|
|
9
10
|
import { formatNumber } from '../utils/format.js';
|
|
10
|
-
import { MarkupDataController } from '../utils/markup-data.js';
|
|
11
11
|
|
|
12
12
|
type CompatibilityData =
|
|
13
13
|
| CalculateCompatibilityResponse
|
|
@@ -19,12 +19,13 @@ type CompatibilityData =
|
|
|
19
19
|
* /numerology/compatibility, or /biorhythm/compatibility responses.
|
|
20
20
|
*/
|
|
21
21
|
@customElement('roxy-compatibility-card')
|
|
22
|
-
export class RoxyCompatibilityCard extends
|
|
22
|
+
export class RoxyCompatibilityCard extends RoxyDataElement<CompatibilityData> {
|
|
23
23
|
static styles = [
|
|
24
24
|
baseStyles,
|
|
25
25
|
css`
|
|
26
26
|
.card {
|
|
27
|
-
background: var(--roxy-
|
|
27
|
+
background: var(--roxy-surface, #fff);
|
|
28
|
+
color: var(--roxy-fg, #0a0a0a);
|
|
28
29
|
border: 1px solid var(--roxy-border, #e4e4e7);
|
|
29
30
|
border-radius: var(--roxy-radius-md, 8px);
|
|
30
31
|
padding: var(--roxy-space-lg, 1.5rem);
|
|
@@ -109,17 +110,6 @@ export class RoxyCompatibilityCard extends LitElement {
|
|
|
109
110
|
`,
|
|
110
111
|
];
|
|
111
112
|
|
|
112
|
-
constructor() {
|
|
113
|
-
super();
|
|
114
|
-
// Enables hydrating `data` from a direct-child
|
|
115
|
-
// <script type="application/json" class="roxy-data"> for server-rendered
|
|
116
|
-
// and cached consumers. The JavaScript `data` property still wins.
|
|
117
|
-
new MarkupDataController(this);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
@property({ attribute: false })
|
|
121
|
-
data: CompatibilityData | null = null;
|
|
122
|
-
|
|
123
113
|
@property({ type: String, reflect: true })
|
|
124
114
|
mode: 'astrology' | 'numerology' | 'biorhythm' = 'astrology';
|
|
125
115
|
|
|
@@ -136,11 +126,11 @@ export class RoxyCompatibilityCard extends LitElement {
|
|
|
136
126
|
return {};
|
|
137
127
|
}
|
|
138
128
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
return html`<div class="roxy-empty" role="status">No compatibility data</div>`;
|
|
129
|
+
protected renderEmpty() {
|
|
130
|
+
return html`<div class="roxy-empty" role="status">No compatibility data</div>`;
|
|
131
|
+
}
|
|
143
132
|
|
|
133
|
+
protected renderData(d: CompatibilityData) {
|
|
144
134
|
const score = d.overallScore;
|
|
145
135
|
const breakdown = this.getBreakdown();
|
|
146
136
|
const rating =
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { css, html, nothing } from 'lit';
|
|
2
|
+
import { customElement } from 'lit/decorators.js';
|
|
3
|
+
import type { GetCrystalResponse } from '../types/index.js';
|
|
4
|
+
import { RoxyDataElement } from '../utils/base-element.js';
|
|
5
|
+
import { baseStyles } from '../utils/base-styles.js';
|
|
6
|
+
|
|
7
|
+
const MONTHS = [
|
|
8
|
+
'January',
|
|
9
|
+
'February',
|
|
10
|
+
'March',
|
|
11
|
+
'April',
|
|
12
|
+
'May',
|
|
13
|
+
'June',
|
|
14
|
+
'July',
|
|
15
|
+
'August',
|
|
16
|
+
'September',
|
|
17
|
+
'October',
|
|
18
|
+
'November',
|
|
19
|
+
'December',
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Single-crystal detail card. Renders /crystals/{id}: the stone's photo, description, and full metaphysical profile (spiritual / emotional / physical meaning, governing chakras, zodiac signs, planet, elements, colours, Mohs hardness, numerical vibration, birthstone month), plus its affirmation and the crystals it pairs with. This is the detail view; roxy-crystal-grid is the gallery.
|
|
24
|
+
*/
|
|
25
|
+
@customElement('roxy-crystal-card')
|
|
26
|
+
export class RoxyCrystalCard extends RoxyDataElement<GetCrystalResponse> {
|
|
27
|
+
static styles = [
|
|
28
|
+
baseStyles,
|
|
29
|
+
css`
|
|
30
|
+
.wrap {
|
|
31
|
+
background: var(--roxy-surface, #fff);
|
|
32
|
+
color: var(--roxy-fg, #0a0a0a);
|
|
33
|
+
border: 1px solid var(--roxy-border, #e4e4e7);
|
|
34
|
+
border-radius: var(--roxy-radius-md, 8px);
|
|
35
|
+
padding: var(--roxy-space-lg, 1.5rem);
|
|
36
|
+
box-shadow: var(--roxy-shadow-sm);
|
|
37
|
+
display: grid;
|
|
38
|
+
gap: var(--roxy-space-md, 1rem);
|
|
39
|
+
}
|
|
40
|
+
.hero {
|
|
41
|
+
display: flex;
|
|
42
|
+
gap: var(--roxy-space-md, 1rem);
|
|
43
|
+
align-items: flex-start;
|
|
44
|
+
}
|
|
45
|
+
.photo {
|
|
46
|
+
width: 96px;
|
|
47
|
+
height: 96px;
|
|
48
|
+
flex: none;
|
|
49
|
+
border-radius: var(--roxy-radius-md, 8px);
|
|
50
|
+
object-fit: cover;
|
|
51
|
+
background: color-mix(in srgb, var(--roxy-border, #e4e4e7) 35%, transparent);
|
|
52
|
+
}
|
|
53
|
+
.title {
|
|
54
|
+
margin: 0 0 var(--roxy-space-xs, 0.25rem) 0;
|
|
55
|
+
font-size: var(--roxy-text-lg, 1.125rem);
|
|
56
|
+
font-weight: var(--roxy-weight-bold, 600);
|
|
57
|
+
}
|
|
58
|
+
.desc {
|
|
59
|
+
margin: 0;
|
|
60
|
+
line-height: 1.55;
|
|
61
|
+
font-size: var(--roxy-text-sm, 0.875rem);
|
|
62
|
+
color: var(--roxy-fg, #0a0a0a);
|
|
63
|
+
}
|
|
64
|
+
.attrs {
|
|
65
|
+
display: grid;
|
|
66
|
+
grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
|
|
67
|
+
gap: var(--roxy-space-sm, 0.5rem);
|
|
68
|
+
}
|
|
69
|
+
.attr {
|
|
70
|
+
display: grid;
|
|
71
|
+
gap: 2px;
|
|
72
|
+
}
|
|
73
|
+
.attr dt {
|
|
74
|
+
font-size: var(--roxy-text-xs, 0.75rem);
|
|
75
|
+
color: var(--roxy-muted, #71717a);
|
|
76
|
+
text-transform: uppercase;
|
|
77
|
+
letter-spacing: 0.05em;
|
|
78
|
+
}
|
|
79
|
+
.attr dd {
|
|
80
|
+
margin: 0;
|
|
81
|
+
font-size: var(--roxy-text-sm, 0.875rem);
|
|
82
|
+
font-weight: 500;
|
|
83
|
+
}
|
|
84
|
+
.colors {
|
|
85
|
+
display: flex;
|
|
86
|
+
flex-wrap: wrap;
|
|
87
|
+
gap: 0.4rem;
|
|
88
|
+
}
|
|
89
|
+
.color {
|
|
90
|
+
display: inline-flex;
|
|
91
|
+
align-items: center;
|
|
92
|
+
gap: 0.3rem;
|
|
93
|
+
font-size: var(--roxy-text-xs, 0.75rem);
|
|
94
|
+
text-transform: capitalize;
|
|
95
|
+
}
|
|
96
|
+
.dot {
|
|
97
|
+
width: 0.7rem;
|
|
98
|
+
height: 0.7rem;
|
|
99
|
+
border-radius: var(--roxy-radius-full, 9999px);
|
|
100
|
+
border: 1px solid color-mix(in srgb, var(--roxy-fg, #0a0a0a) 18%, transparent);
|
|
101
|
+
}
|
|
102
|
+
.meaning h3 {
|
|
103
|
+
margin: 0 0 var(--roxy-space-xs, 0.25rem) 0;
|
|
104
|
+
font-size: var(--roxy-text-xs, 0.75rem);
|
|
105
|
+
color: var(--roxy-muted, #71717a);
|
|
106
|
+
text-transform: uppercase;
|
|
107
|
+
letter-spacing: 0.05em;
|
|
108
|
+
}
|
|
109
|
+
.meaning p {
|
|
110
|
+
margin: 0 0 var(--roxy-space-sm, 0.5rem) 0;
|
|
111
|
+
font-size: var(--roxy-text-sm, 0.875rem);
|
|
112
|
+
line-height: 1.55;
|
|
113
|
+
}
|
|
114
|
+
.chips {
|
|
115
|
+
display: flex;
|
|
116
|
+
flex-wrap: wrap;
|
|
117
|
+
gap: 0.3rem;
|
|
118
|
+
}
|
|
119
|
+
.chip {
|
|
120
|
+
padding: 1px 8px;
|
|
121
|
+
border-radius: var(--roxy-radius-full, 9999px);
|
|
122
|
+
background: color-mix(in srgb, var(--roxy-accent, #f59e0b) 14%, transparent);
|
|
123
|
+
color: var(--roxy-fg, #0a0a0a);
|
|
124
|
+
font-size: var(--roxy-text-xs, 0.75rem);
|
|
125
|
+
text-transform: capitalize;
|
|
126
|
+
}
|
|
127
|
+
.section-label {
|
|
128
|
+
font-size: var(--roxy-text-xs, 0.75rem);
|
|
129
|
+
color: var(--roxy-muted, #71717a);
|
|
130
|
+
text-transform: uppercase;
|
|
131
|
+
letter-spacing: 0.06em;
|
|
132
|
+
font-weight: var(--roxy-weight-bold, 600);
|
|
133
|
+
margin: 0 0 var(--roxy-space-xs, 0.25rem) 0;
|
|
134
|
+
}
|
|
135
|
+
.affirmation {
|
|
136
|
+
margin: 0;
|
|
137
|
+
padding: var(--roxy-space-sm, 0.5rem) var(--roxy-space-md, 1rem);
|
|
138
|
+
border-left: 3px solid var(--roxy-accent, #f59e0b);
|
|
139
|
+
background: color-mix(in srgb, var(--roxy-accent, #f59e0b) 8%, transparent);
|
|
140
|
+
font-style: italic;
|
|
141
|
+
font-size: var(--roxy-text-sm, 0.875rem);
|
|
142
|
+
border-radius: 0 var(--roxy-radius-sm, 4px) var(--roxy-radius-sm, 4px) 0;
|
|
143
|
+
}
|
|
144
|
+
`,
|
|
145
|
+
];
|
|
146
|
+
|
|
147
|
+
protected renderEmpty() {
|
|
148
|
+
return html`<div class="roxy-empty" role="status">No crystal data</div>`;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
protected renderData(d: GetCrystalResponse) {
|
|
152
|
+
const colors = d.colors ?? [];
|
|
153
|
+
const keywords = d.keywords ?? [];
|
|
154
|
+
const pairs = d.pairsWith ?? [];
|
|
155
|
+
const month =
|
|
156
|
+
typeof d.birthMonth === 'number' ? MONTHS[d.birthMonth - 1] : undefined;
|
|
157
|
+
|
|
158
|
+
return html`<article class="wrap" aria-label=${d.name ?? 'Crystal'}>
|
|
159
|
+
<div class="hero">
|
|
160
|
+
${d.imageUrl ? html`<img class="photo" src=${d.imageUrl} alt=${d.name ?? 'Crystal'} loading="lazy" />` : nothing}
|
|
161
|
+
<div>
|
|
162
|
+
<h2 class="title">${d.name}</h2>
|
|
163
|
+
${d.description ? html`<p class="desc">${d.description}</p>` : nothing}
|
|
164
|
+
</div>
|
|
165
|
+
</div>
|
|
166
|
+
|
|
167
|
+
<dl class="attrs">
|
|
168
|
+
${this.attr('Planet', d.planet)}
|
|
169
|
+
${this.attr('Hardness', typeof d.hardness === 'number' ? `${d.hardness} Mohs` : undefined)}
|
|
170
|
+
${this.attr('Vibration', d.numericalVibration)}
|
|
171
|
+
${this.attr('Birthstone', month)}
|
|
172
|
+
${this.list('Chakras', d.chakras)}
|
|
173
|
+
${this.list('Zodiac', d.zodiacSigns)}
|
|
174
|
+
${this.list('Elements', d.elements)}
|
|
175
|
+
${
|
|
176
|
+
colors.length
|
|
177
|
+
? html`<div class="attr">
|
|
178
|
+
<dt>Colors</dt>
|
|
179
|
+
<dd>
|
|
180
|
+
<div class="colors">
|
|
181
|
+
${colors.map((c) => html`<span class="color"><span class="dot" style="background:${c}"></span>${c}</span>`)}
|
|
182
|
+
</div>
|
|
183
|
+
</dd>
|
|
184
|
+
</div>`
|
|
185
|
+
: nothing
|
|
186
|
+
}
|
|
187
|
+
</dl>
|
|
188
|
+
|
|
189
|
+
${this.renderMeaning(d.meaning)}
|
|
190
|
+
|
|
191
|
+
${
|
|
192
|
+
keywords.length
|
|
193
|
+
? html`<div>
|
|
194
|
+
<p class="section-label">Keywords</p>
|
|
195
|
+
<div class="chips">${keywords.map((k) => html`<span class="chip">${k}</span>`)}</div>
|
|
196
|
+
</div>`
|
|
197
|
+
: nothing
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
${d.affirmation ? html`<p class="affirmation">${d.affirmation}</p>` : nothing}
|
|
201
|
+
|
|
202
|
+
${
|
|
203
|
+
pairs.length
|
|
204
|
+
? html`<div>
|
|
205
|
+
<p class="section-label">Pairs with</p>
|
|
206
|
+
<div class="chips">${pairs.map((p) => html`<span class="chip">${String(p).replace(/-/g, ' ')}</span>`)}</div>
|
|
207
|
+
</div>`
|
|
208
|
+
: nothing
|
|
209
|
+
}
|
|
210
|
+
</article>`;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
private attr(label: string, value: string | number | undefined) {
|
|
214
|
+
if (value === undefined || value === null || value === '') return nothing;
|
|
215
|
+
return html`<div class="attr"><dt>${label}</dt><dd>${value}</dd></div>`;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
private list(label: string, values: readonly string[] | undefined) {
|
|
219
|
+
if (!values?.length) return nothing;
|
|
220
|
+
return html`<div class="attr"><dt>${label}</dt><dd>${values.join(', ')}</dd></div>`;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
private renderMeaning(m: GetCrystalResponse['meaning'] | undefined) {
|
|
224
|
+
if (!m) return nothing;
|
|
225
|
+
const rows: Array<[string, string | undefined]> = [
|
|
226
|
+
['Spiritual', m.spiritual],
|
|
227
|
+
['Emotional', m.emotional],
|
|
228
|
+
['Physical', m.physical],
|
|
229
|
+
];
|
|
230
|
+
const present = rows.filter(([, v]) => Boolean(v));
|
|
231
|
+
if (present.length === 0) return nothing;
|
|
232
|
+
return html`<div class="meaning">
|
|
233
|
+
${present.map(([label, text]) => html`<h3>${label}</h3><p>${text}</p>`)}
|
|
234
|
+
</div>`;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
declare global {
|
|
239
|
+
interface HTMLElementTagNameMap {
|
|
240
|
+
'roxy-crystal-card': RoxyCrystalCard;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { css, html, 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 { RoxyDataElement } from '../utils/base-element.js';
|
|
12
|
+
import { baseStyles } from '../utils/base-styles.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 RoxyDataElement<CrystalGridData> {
|
|
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-surface, #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
|
+
/**
|
|
117
|
+
* 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".
|
|
118
|
+
*/
|
|
119
|
+
@property({ type: String, reflect: true })
|
|
120
|
+
heading = '';
|
|
121
|
+
|
|
122
|
+
protected renderEmpty() {
|
|
123
|
+
return html`<div class="roxy-empty" role="status">No crystals</div>`;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
protected renderData(d: CrystalGridData) {
|
|
127
|
+
const crystals = d.crystals ?? [];
|
|
128
|
+
if (crystals.length === 0) return this.renderEmpty();
|
|
129
|
+
|
|
130
|
+
const title = this.heading || this.deriveHeading(d);
|
|
131
|
+
const total =
|
|
132
|
+
'total' in d && typeof d.total === 'number' ? d.total : crystals.length;
|
|
133
|
+
|
|
134
|
+
return html`<section class="wrap" aria-label=${title}>
|
|
135
|
+
<header class="head">
|
|
136
|
+
<h2 class="title">${title}</h2>
|
|
137
|
+
<span class="count">${total} ${total === 1 ? 'crystal' : 'crystals'}</span>
|
|
138
|
+
</header>
|
|
139
|
+
<ul class="grid">
|
|
140
|
+
${crystals.map(
|
|
141
|
+
(c) => html`<li class="tile">
|
|
142
|
+
${
|
|
143
|
+
c.imageUrl
|
|
144
|
+
? html`<img class="photo" src=${c.imageUrl} alt=${c.name ?? 'Crystal'} loading="lazy" />`
|
|
145
|
+
: html`<div class="photo" aria-hidden="true"></div>`
|
|
146
|
+
}
|
|
147
|
+
<p class="name">${c.name}</p>
|
|
148
|
+
${
|
|
149
|
+
c.colors && c.colors.length > 0
|
|
150
|
+
? html`<div class="colors" aria-label=${`Colours: ${c.colors.join(', ')}`}>
|
|
151
|
+
${c.colors.map((col) => html`<span class="swatch" style=${`background:${cssColor(col)}`} title=${col}></span>`)}
|
|
152
|
+
</div>`
|
|
153
|
+
: nothing
|
|
154
|
+
}
|
|
155
|
+
</li>`,
|
|
156
|
+
)}
|
|
157
|
+
</ul>
|
|
158
|
+
</section>`;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
private deriveHeading(d: CrystalGridData): string {
|
|
162
|
+
if ('chakra' in d && d.chakra) return `${d.chakra} chakra crystals`;
|
|
163
|
+
if ('element' in d && d.element) return `${d.element} element crystals`;
|
|
164
|
+
if ('sign' in d && d.sign) return `Crystals for ${d.sign}`;
|
|
165
|
+
if ('month' in d && typeof d.month === 'number')
|
|
166
|
+
return `${MONTHS[d.month - 1] ?? ''} birthstones`.trim();
|
|
167
|
+
return 'Crystals';
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* 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.
|
|
173
|
+
*/
|
|
174
|
+
function cssColor(name: string): string {
|
|
175
|
+
return name.trim().toLowerCase().replace(/\s+/g, '');
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
declare global {
|
|
179
|
+
interface HTMLElementTagNameMap {
|
|
180
|
+
'roxy-crystal-grid': RoxyCrystalGrid;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { css, html,
|
|
1
|
+
import { css, html, nothing } from 'lit';
|
|
2
2
|
import { customElement, property } from 'lit/decorators.js';
|
|
3
3
|
import type {
|
|
4
4
|
GetCurrentDashaResponse,
|
|
5
5
|
GetMajorDashasResponse,
|
|
6
6
|
GetSubDashasResponse,
|
|
7
7
|
} from '../types/index.js';
|
|
8
|
+
import { RoxyDataElement } from '../utils/base-element.js';
|
|
8
9
|
import { baseStyles } from '../utils/base-styles.js';
|
|
9
10
|
import { formatNumber } from '../utils/format.js';
|
|
10
|
-
import { MarkupDataController } from '../utils/markup-data.js';
|
|
11
11
|
|
|
12
12
|
type DashaData =
|
|
13
13
|
| GetCurrentDashaResponse
|
|
@@ -22,7 +22,7 @@ type DashaPeriod = GetMajorDashasResponse['mahadashas'][number];
|
|
|
22
22
|
* Switch to period="major" for the full 120-year Vimshottari timeline.
|
|
23
23
|
*/
|
|
24
24
|
@customElement('roxy-dasha-timeline')
|
|
25
|
-
export class RoxyDashaTimeline extends
|
|
25
|
+
export class RoxyDashaTimeline extends RoxyDataElement<DashaData> {
|
|
26
26
|
static styles = [
|
|
27
27
|
baseStyles,
|
|
28
28
|
css`
|
|
@@ -51,7 +51,7 @@ export class RoxyDashaTimeline extends LitElement {
|
|
|
51
51
|
display: grid;
|
|
52
52
|
grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
|
|
53
53
|
gap: var(--roxy-space-md, 1rem);
|
|
54
|
-
background: var(--roxy-
|
|
54
|
+
background: var(--roxy-surface, #fff);
|
|
55
55
|
border: 1px solid var(--roxy-border, #e4e4e7);
|
|
56
56
|
border-radius: var(--roxy-radius-md, 8px);
|
|
57
57
|
padding: var(--roxy-space-md, 1rem);
|
|
@@ -138,7 +138,7 @@ export class RoxyDashaTimeline extends LitElement {
|
|
|
138
138
|
border: 1px solid var(--roxy-border, #e4e4e7);
|
|
139
139
|
border-radius: var(--roxy-radius-md, 8px);
|
|
140
140
|
padding: var(--roxy-space-sm, 0.5rem) var(--roxy-space-md, 1rem);
|
|
141
|
-
background: var(--roxy-
|
|
141
|
+
background: var(--roxy-surface, #fff);
|
|
142
142
|
}
|
|
143
143
|
.interp h3 {
|
|
144
144
|
margin: 0;
|
|
@@ -153,25 +153,14 @@ export class RoxyDashaTimeline extends LitElement {
|
|
|
153
153
|
`,
|
|
154
154
|
];
|
|
155
155
|
|
|
156
|
-
constructor() {
|
|
157
|
-
super();
|
|
158
|
-
// Enables hydrating `data` from a direct-child
|
|
159
|
-
// <script type="application/json" class="roxy-data"> for server-rendered
|
|
160
|
-
// and cached consumers. The JavaScript `data` property still wins.
|
|
161
|
-
new MarkupDataController(this);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
@property({ attribute: false })
|
|
165
|
-
data: DashaData | null = null;
|
|
166
|
-
|
|
167
156
|
@property({ type: String, reflect: true })
|
|
168
157
|
period: 'current' | 'major' | 'sub' = 'current';
|
|
169
158
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
return html`<div class="roxy-empty" role="status">No dasha data</div>`;
|
|
159
|
+
protected renderEmpty() {
|
|
160
|
+
return html`<div class="roxy-empty" role="status">No dasha data</div>`;
|
|
161
|
+
}
|
|
174
162
|
|
|
163
|
+
protected renderData(d: DashaData) {
|
|
175
164
|
const periods = this.collectPeriods(d);
|
|
176
165
|
const maxYears = periods.length
|
|
177
166
|
? Math.max(...periods.map((p) => p.durationYears))
|