@crediball/elements 0.11.0 → 0.12.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.
|
@@ -2,22 +2,33 @@
|
|
|
2
2
|
import {
|
|
3
3
|
getCrediballClient,
|
|
4
4
|
loadRemoteFont,
|
|
5
|
-
themeToCssVars
|
|
5
|
+
themeToCssVars,
|
|
6
|
+
getSystemColorScheme,
|
|
7
|
+
watchSystemColorScheme
|
|
6
8
|
} from "@crediball/core";
|
|
7
9
|
var _CrediballElement = class _CrediballElement extends HTMLElement {
|
|
8
10
|
constructor() {
|
|
9
11
|
super(...arguments);
|
|
10
12
|
this.client = null;
|
|
11
13
|
this.unsubscribe = null;
|
|
14
|
+
this.unwatchSystemColorScheme = null;
|
|
12
15
|
}
|
|
13
16
|
static get observedAttributes() {
|
|
14
|
-
return [..._CrediballElement.CLIENT_ATTRS];
|
|
17
|
+
return [..._CrediballElement.CLIENT_ATTRS, "color-scheme"];
|
|
15
18
|
}
|
|
16
19
|
connectedCallback() {
|
|
17
20
|
this.connectClient();
|
|
21
|
+
this.unwatchSystemColorScheme = watchSystemColorScheme(() => {
|
|
22
|
+
if (!this.explicitColorScheme()) {
|
|
23
|
+
this.applyRemoteTheme();
|
|
24
|
+
this.render();
|
|
25
|
+
}
|
|
26
|
+
});
|
|
18
27
|
}
|
|
19
28
|
disconnectedCallback() {
|
|
20
29
|
this.teardownClient();
|
|
30
|
+
this.unwatchSystemColorScheme?.();
|
|
31
|
+
this.unwatchSystemColorScheme = null;
|
|
21
32
|
}
|
|
22
33
|
/**
|
|
23
34
|
* Only reconnect the shared client when a connection-relevant attribute
|
|
@@ -29,10 +40,21 @@ var _CrediballElement = class _CrediballElement extends HTMLElement {
|
|
|
29
40
|
if (!this.isConnected) return;
|
|
30
41
|
if (_CrediballElement.CLIENT_ATTRS.has(name)) {
|
|
31
42
|
this.connectClient();
|
|
43
|
+
} else if (name === "color-scheme") {
|
|
44
|
+
this.applyRemoteTheme();
|
|
45
|
+
this.render();
|
|
32
46
|
} else {
|
|
33
47
|
this.render();
|
|
34
48
|
}
|
|
35
49
|
}
|
|
50
|
+
explicitColorScheme() {
|
|
51
|
+
const attr = this.getAttribute("color-scheme");
|
|
52
|
+
return attr === "light" || attr === "dark" ? attr : null;
|
|
53
|
+
}
|
|
54
|
+
/** "light"/"dark" attribute wins; otherwise follows the live OS/browser preference. */
|
|
55
|
+
resolvedColorScheme() {
|
|
56
|
+
return this.explicitColorScheme() ?? getSystemColorScheme();
|
|
57
|
+
}
|
|
36
58
|
connectClient() {
|
|
37
59
|
this.teardownClient();
|
|
38
60
|
const publishableKey = this.getAttribute("publishable-key");
|
|
@@ -59,12 +81,18 @@ var _CrediballElement = class _CrediballElement extends HTMLElement {
|
|
|
59
81
|
* the shadow boundary, so the shadow-DOM styles pick them up. On by default;
|
|
60
82
|
* set `apply-remote-theme="false"` to theme from your own CSS instead. The
|
|
61
83
|
* published theme takes precedence over host `--crediball-*` vars (dashboard wins).
|
|
84
|
+
*
|
|
85
|
+
* If a dark palette is configured on the dashboard, it's applied whenever
|
|
86
|
+
* the resolved color scheme is "dark" — following the OS/browser's
|
|
87
|
+
* `prefers-color-scheme` live, or a `color-scheme="light"|"dark"` attribute
|
|
88
|
+
* you set explicitly (wins over the OS setting, for an app with its own
|
|
89
|
+
* in-app theme toggle).
|
|
62
90
|
*/
|
|
63
91
|
applyRemoteTheme() {
|
|
64
92
|
if (this.getAttribute("apply-remote-theme") === "false") return;
|
|
65
93
|
const theme = this.getSnapshot()?.packages?.ui?.theme;
|
|
66
94
|
if (!theme) return;
|
|
67
|
-
for (const [cssVar, value] of Object.entries(themeToCssVars(theme))) {
|
|
95
|
+
for (const [cssVar, value] of Object.entries(themeToCssVars(theme, this.resolvedColorScheme()))) {
|
|
68
96
|
this.style.setProperty(cssVar, value);
|
|
69
97
|
}
|
|
70
98
|
if (theme.fontUrl) loadRemoteFont(theme.fontUrl);
|
|
@@ -480,8 +508,8 @@ var CrediballPaywallElement = class extends CrediballElement {
|
|
|
480
508
|
</div>
|
|
481
509
|
<p class="custom-preview" hidden></p>` : ""}
|
|
482
510
|
${this.renderPromoCode(Boolean(pkgs?.hasActiveCheckoutPromotion))}
|
|
483
|
-
${this.renderAutoTopup(packages, pkgs?.autoTopup, currency)}
|
|
484
511
|
<p class="error" hidden></p>
|
|
512
|
+
${this.renderAutoTopup(packages, pkgs?.autoTopup, currency)}
|
|
485
513
|
<button class="close" part="close" type="button">Not now</button>
|
|
486
514
|
${this.referral?.link ? `<div class="referral">
|
|
487
515
|
<div class="referral-label">${escapeHtml(referralLabel)}</div>
|
|
@@ -384,6 +384,27 @@ var Crediball = (() => {
|
|
|
384
384
|
}
|
|
385
385
|
|
|
386
386
|
// ../core/dist/theme.js
|
|
387
|
+
function getSystemColorScheme() {
|
|
388
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function")
|
|
389
|
+
return "light";
|
|
390
|
+
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
391
|
+
}
|
|
392
|
+
function watchSystemColorScheme(cb) {
|
|
393
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function")
|
|
394
|
+
return () => {
|
|
395
|
+
};
|
|
396
|
+
const mql = window.matchMedia("(prefers-color-scheme: dark)");
|
|
397
|
+
const handler = () => cb(mql.matches ? "dark" : "light");
|
|
398
|
+
mql.addEventListener("change", handler);
|
|
399
|
+
return () => mql.removeEventListener("change", handler);
|
|
400
|
+
}
|
|
401
|
+
function resolveUiTheme(theme, scheme) {
|
|
402
|
+
if (!theme)
|
|
403
|
+
return theme ?? null;
|
|
404
|
+
if (scheme !== "dark" || !theme.dark)
|
|
405
|
+
return theme;
|
|
406
|
+
return { ...theme, ...theme.dark };
|
|
407
|
+
}
|
|
387
408
|
var THEME_CSS_VAR_ENTRIES = [
|
|
388
409
|
["accent", "--crediball-accent", String],
|
|
389
410
|
["onAccent", "--crediball-on-accent", String],
|
|
@@ -394,12 +415,13 @@ var Crediball = (() => {
|
|
|
394
415
|
["radiusCard", "--crediball-radius-card", (v) => `${v}px`],
|
|
395
416
|
["fontStack", "--crediball-font", String]
|
|
396
417
|
];
|
|
397
|
-
function themeToCssVars(theme) {
|
|
418
|
+
function themeToCssVars(theme, scheme = "light") {
|
|
398
419
|
const vars = {};
|
|
399
|
-
|
|
420
|
+
const resolved = resolveUiTheme(theme, scheme);
|
|
421
|
+
if (!resolved)
|
|
400
422
|
return vars;
|
|
401
423
|
for (const [key, cssVar, fmt] of THEME_CSS_VAR_ENTRIES) {
|
|
402
|
-
const value =
|
|
424
|
+
const value = resolved[key];
|
|
403
425
|
if (value != null && value !== "")
|
|
404
426
|
vars[cssVar] = fmt(value);
|
|
405
427
|
}
|
|
@@ -428,15 +450,24 @@ var Crediball = (() => {
|
|
|
428
450
|
super(...arguments);
|
|
429
451
|
this.client = null;
|
|
430
452
|
this.unsubscribe = null;
|
|
453
|
+
this.unwatchSystemColorScheme = null;
|
|
431
454
|
}
|
|
432
455
|
static get observedAttributes() {
|
|
433
|
-
return [..._CrediballElement.CLIENT_ATTRS];
|
|
456
|
+
return [..._CrediballElement.CLIENT_ATTRS, "color-scheme"];
|
|
434
457
|
}
|
|
435
458
|
connectedCallback() {
|
|
436
459
|
this.connectClient();
|
|
460
|
+
this.unwatchSystemColorScheme = watchSystemColorScheme(() => {
|
|
461
|
+
if (!this.explicitColorScheme()) {
|
|
462
|
+
this.applyRemoteTheme();
|
|
463
|
+
this.render();
|
|
464
|
+
}
|
|
465
|
+
});
|
|
437
466
|
}
|
|
438
467
|
disconnectedCallback() {
|
|
439
468
|
this.teardownClient();
|
|
469
|
+
this.unwatchSystemColorScheme?.();
|
|
470
|
+
this.unwatchSystemColorScheme = null;
|
|
440
471
|
}
|
|
441
472
|
/**
|
|
442
473
|
* Only reconnect the shared client when a connection-relevant attribute
|
|
@@ -448,10 +479,21 @@ var Crediball = (() => {
|
|
|
448
479
|
if (!this.isConnected) return;
|
|
449
480
|
if (_CrediballElement.CLIENT_ATTRS.has(name)) {
|
|
450
481
|
this.connectClient();
|
|
482
|
+
} else if (name === "color-scheme") {
|
|
483
|
+
this.applyRemoteTheme();
|
|
484
|
+
this.render();
|
|
451
485
|
} else {
|
|
452
486
|
this.render();
|
|
453
487
|
}
|
|
454
488
|
}
|
|
489
|
+
explicitColorScheme() {
|
|
490
|
+
const attr = this.getAttribute("color-scheme");
|
|
491
|
+
return attr === "light" || attr === "dark" ? attr : null;
|
|
492
|
+
}
|
|
493
|
+
/** "light"/"dark" attribute wins; otherwise follows the live OS/browser preference. */
|
|
494
|
+
resolvedColorScheme() {
|
|
495
|
+
return this.explicitColorScheme() ?? getSystemColorScheme();
|
|
496
|
+
}
|
|
455
497
|
connectClient() {
|
|
456
498
|
this.teardownClient();
|
|
457
499
|
const publishableKey = this.getAttribute("publishable-key");
|
|
@@ -478,12 +520,18 @@ var Crediball = (() => {
|
|
|
478
520
|
* the shadow boundary, so the shadow-DOM styles pick them up. On by default;
|
|
479
521
|
* set `apply-remote-theme="false"` to theme from your own CSS instead. The
|
|
480
522
|
* published theme takes precedence over host `--crediball-*` vars (dashboard wins).
|
|
523
|
+
*
|
|
524
|
+
* If a dark palette is configured on the dashboard, it's applied whenever
|
|
525
|
+
* the resolved color scheme is "dark" — following the OS/browser's
|
|
526
|
+
* `prefers-color-scheme` live, or a `color-scheme="light"|"dark"` attribute
|
|
527
|
+
* you set explicitly (wins over the OS setting, for an app with its own
|
|
528
|
+
* in-app theme toggle).
|
|
481
529
|
*/
|
|
482
530
|
applyRemoteTheme() {
|
|
483
531
|
if (this.getAttribute("apply-remote-theme") === "false") return;
|
|
484
532
|
const theme = this.getSnapshot()?.packages?.ui?.theme;
|
|
485
533
|
if (!theme) return;
|
|
486
|
-
for (const [cssVar, value] of Object.entries(themeToCssVars(theme))) {
|
|
534
|
+
for (const [cssVar, value] of Object.entries(themeToCssVars(theme, this.resolvedColorScheme()))) {
|
|
487
535
|
this.style.setProperty(cssVar, value);
|
|
488
536
|
}
|
|
489
537
|
if (theme.fontUrl) loadRemoteFont(theme.fontUrl);
|
|
@@ -894,8 +942,8 @@ var Crediball = (() => {
|
|
|
894
942
|
</div>
|
|
895
943
|
<p class="custom-preview" hidden></p>` : ""}
|
|
896
944
|
${this.renderPromoCode(Boolean(pkgs?.hasActiveCheckoutPromotion))}
|
|
897
|
-
${this.renderAutoTopup(packages, pkgs?.autoTopup, currency)}
|
|
898
945
|
<p class="error" hidden></p>
|
|
946
|
+
${this.renderAutoTopup(packages, pkgs?.autoTopup, currency)}
|
|
899
947
|
<button class="close" part="close" type="button">Not now</button>
|
|
900
948
|
${this.referral?.link ? `<div class="referral">
|
|
901
949
|
<div class="referral-label">${escapeHtml(referralLabel)}</div>
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CrediballClient, CrediballSnapshot } from '@crediball/core';
|
|
1
|
+
import { CrediballClient, ColorScheme, CrediballSnapshot } from '@crediball/core';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Shared base for every <crediball-*> element: reads config from attributes,
|
|
@@ -12,6 +12,7 @@ import { CrediballClient, CrediballSnapshot } from '@crediball/core';
|
|
|
12
12
|
declare abstract class CrediballElement extends HTMLElement {
|
|
13
13
|
protected client: CrediballClient | null;
|
|
14
14
|
private unsubscribe;
|
|
15
|
+
private unwatchSystemColorScheme;
|
|
15
16
|
private static readonly CLIENT_ATTRS;
|
|
16
17
|
static get observedAttributes(): string[];
|
|
17
18
|
connectedCallback(): void;
|
|
@@ -23,6 +24,9 @@ declare abstract class CrediballElement extends HTMLElement {
|
|
|
23
24
|
* those should just re-render, not tear down and refetch the client.
|
|
24
25
|
*/
|
|
25
26
|
attributeChangedCallback(name: string): void;
|
|
27
|
+
private explicitColorScheme;
|
|
28
|
+
/** "light"/"dark" attribute wins; otherwise follows the live OS/browser preference. */
|
|
29
|
+
protected resolvedColorScheme(): ColorScheme;
|
|
26
30
|
private connectClient;
|
|
27
31
|
/**
|
|
28
32
|
* Apply the developer-published theme (served alongside packages) as
|
|
@@ -30,6 +34,12 @@ declare abstract class CrediballElement extends HTMLElement {
|
|
|
30
34
|
* the shadow boundary, so the shadow-DOM styles pick them up. On by default;
|
|
31
35
|
* set `apply-remote-theme="false"` to theme from your own CSS instead. The
|
|
32
36
|
* published theme takes precedence over host `--crediball-*` vars (dashboard wins).
|
|
37
|
+
*
|
|
38
|
+
* If a dark palette is configured on the dashboard, it's applied whenever
|
|
39
|
+
* the resolved color scheme is "dark" — following the OS/browser's
|
|
40
|
+
* `prefers-color-scheme` live, or a `color-scheme="light"|"dark"` attribute
|
|
41
|
+
* you set explicitly (wins over the OS setting, for an app with its own
|
|
42
|
+
* in-app theme toggle).
|
|
33
43
|
*/
|
|
34
44
|
private applyRemoteTheme;
|
|
35
45
|
private teardownClient;
|
package/dist/index.js
CHANGED
package/dist/register.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crediball/elements",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Framework-agnostic web components for showing Crediball credits inside your AI app.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Filippo Rezzadore <filipporezzadore@gmail.com>",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"prepublishOnly": "npm run build"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@crediball/core": "^0.
|
|
59
|
+
"@crediball/core": "^0.10.0"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"tsup": "^8.3.5",
|