@revenuecat/purchases-ui-js 0.0.20 → 0.1.21
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/dist/components/button/Button.svelte +9 -0
- package/dist/components/button/ButtonNode.stories.svelte +3 -3
- package/dist/components/button/ButtonNode.svelte +7 -5
- package/dist/components/footer/Footer.stories.svelte +2 -2
- package/dist/components/image/Image.stories.svelte +2 -2
- package/dist/components/image/Image.svelte +5 -4
- package/dist/components/package/Package.stories.svelte +2 -2
- package/dist/components/paywall/Paywall.svelte +3 -8
- package/dist/components/paywall/Paywall.svelte.d.ts +3 -2
- package/dist/components/paywall/paywall-utils.d.ts +1 -1
- package/dist/components/paywall/paywall-utils.js +2 -1
- package/dist/components/purchase-button/PurchaseButton.stories.svelte +3 -2
- package/dist/components/purchase-button/PurchaseButton.svelte +3 -3
- package/dist/components/stack/Stack.stories.svelte +31 -26
- package/dist/components/text/TextNode.stories.svelte +6 -5
- package/dist/components/text/text-utils.js +3 -2
- package/dist/components/timeline/Timeline.stories.svelte +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/stories/fixtures.d.ts +2 -0
- package/dist/stories/fixtures.js +36 -0
- package/dist/stories/meta-templates.js +7 -3
- package/dist/stories/with-layout.d.ts +10 -0
- package/dist/stories/with-layout.js +15 -0
- package/dist/stories/with-layout.svelte +33 -0
- package/dist/stories/with-layout.svelte.d.ts +10 -0
- package/dist/ui/atoms/typography.stories.svelte +202 -0
- package/dist/ui/atoms/typography.stories.svelte.d.ts +19 -0
- package/dist/ui/atoms/typography.svelte +132 -0
- package/dist/ui/atoms/typography.svelte.d.ts +9 -0
- package/dist/ui/layout/container.svelte +73 -0
- package/dist/ui/layout/container.svelte.d.ts +24 -0
- package/dist/ui/layout/layout.svelte +45 -0
- package/dist/ui/layout/layout.svelte.d.ts +22 -0
- package/dist/ui/layout/main-block.svelte +32 -0
- package/dist/ui/layout/main-block.svelte.d.ts +23 -0
- package/dist/ui/layout/section-layout.svelte +73 -0
- package/dist/ui/layout/section-layout.svelte.d.ts +23 -0
- package/dist/ui/molecules/button.stories.svelte +45 -0
- package/dist/ui/molecules/button.stories.svelte.d.ts +19 -0
- package/dist/ui/molecules/button.svelte +94 -0
- package/dist/ui/molecules/button.svelte.d.ts +13 -0
- package/dist/ui/theme/colors.d.ts +37 -0
- package/dist/ui/theme/colors.js +54 -0
- package/dist/ui/theme/shapes.d.ts +8 -0
- package/dist/ui/theme/shapes.js +13 -0
- package/dist/ui/theme/spacing.d.ts +7 -0
- package/dist/ui/theme/spacing.js +42 -0
- package/dist/ui/theme/text.d.ts +19 -0
- package/dist/ui/theme/text.js +173 -0
- package/dist/ui/theme/theme.d.ts +15 -0
- package/dist/ui/theme/theme.js +38 -0
- package/dist/ui/theme/utils.d.ts +37 -0
- package/dist/ui/theme/utils.js +191 -0
- package/dist/ui/utils/branding.d.ts +16 -0
- package/dist/ui/utils/branding.js +1 -0
- package/dist/ui/utils/processing-animation.svelte +57 -0
- package/dist/ui/utils/processing-animation.svelte.d.ts +20 -0
- package/dist/utils/constants.d.ts +4 -0
- package/dist/utils/constants.js +3 -0
- package/dist/utils/style-utils.js +9 -8
- package/package.json +26 -26
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { toFormColors, toFormStyleVar, toProductInfoStyleVar, toShape, toSpacingVars, toTextStyleVar, } from "./utils";
|
|
2
|
+
import { DEFAULT_TEXT_STYLES } from "./text";
|
|
3
|
+
import { DEFAULT_SPACING } from "./spacing";
|
|
4
|
+
export class Theme {
|
|
5
|
+
brandingAppearance;
|
|
6
|
+
constructor(brandingAppearance) {
|
|
7
|
+
if (brandingAppearance) {
|
|
8
|
+
this.brandingAppearance = brandingAppearance;
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
this.brandingAppearance = undefined;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
get shape() {
|
|
15
|
+
return toShape(this.brandingAppearance);
|
|
16
|
+
}
|
|
17
|
+
get formColors() {
|
|
18
|
+
return toFormColors(this.brandingAppearance);
|
|
19
|
+
}
|
|
20
|
+
get formStyleVars() {
|
|
21
|
+
return toFormStyleVar(this.brandingAppearance);
|
|
22
|
+
}
|
|
23
|
+
get productInfoStyleVars() {
|
|
24
|
+
return toProductInfoStyleVar(this.brandingAppearance);
|
|
25
|
+
}
|
|
26
|
+
get spacing() {
|
|
27
|
+
return DEFAULT_SPACING;
|
|
28
|
+
}
|
|
29
|
+
get textStyles() {
|
|
30
|
+
return DEFAULT_TEXT_STYLES;
|
|
31
|
+
}
|
|
32
|
+
get textStyleVars() {
|
|
33
|
+
return toTextStyleVar("text", this.textStyles);
|
|
34
|
+
}
|
|
35
|
+
get spacingStyleVars() {
|
|
36
|
+
return toSpacingVars("spacing", this.spacing);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type Colors } from "./colors";
|
|
2
|
+
import { type Shape } from "./shapes";
|
|
3
|
+
import { type TextStyles } from "./text";
|
|
4
|
+
import type { Spacing } from "./spacing";
|
|
5
|
+
import type { BrandingAppearance } from "../utils/branding";
|
|
6
|
+
export declare const DEFAULT_LUMINANCE_THRESHOLD = 0.37;
|
|
7
|
+
/**
|
|
8
|
+
* Applies an alpha value to a color.
|
|
9
|
+
* If the base color is light, the overlay color is black.
|
|
10
|
+
* If the base color is dark, the overlay color is white.
|
|
11
|
+
*/
|
|
12
|
+
export declare function applyAlpha(baseColor: string, alpha: number): string;
|
|
13
|
+
export declare const toColors: (colorsMapping: Record<string, string>, defaultColors: Colors, brandingAppearance?: BrandingAppearance | null | undefined) => Colors;
|
|
14
|
+
export declare const toProductInfoColors: (brandingAppearance?: BrandingAppearance | null | undefined) => Colors;
|
|
15
|
+
export declare const toFormColors: (brandingAppearance?: BrandingAppearance | null | undefined) => Colors;
|
|
16
|
+
export declare const toShape: (brandingAppearance?: BrandingAppearance | null | undefined) => Shape;
|
|
17
|
+
export declare const toStyleVar: (prefix: string | undefined, entries: [string, string][]) => string;
|
|
18
|
+
/**
|
|
19
|
+
* Assigns values to the css variables given the branding appearance customization.
|
|
20
|
+
* @param appearance BrandingAppearance
|
|
21
|
+
* @return a style parameter compatible string.
|
|
22
|
+
*/
|
|
23
|
+
export declare const toProductInfoStyleVar: (appearance?: BrandingAppearance | null) => string;
|
|
24
|
+
/**
|
|
25
|
+
* Assigns values to the css variables given the branding appearance customization.
|
|
26
|
+
* @param appearance BrandingAppearance
|
|
27
|
+
* @return a style parameter compatible string.
|
|
28
|
+
*/
|
|
29
|
+
export declare const toFormStyleVar: (appearance?: BrandingAppearance | null) => string;
|
|
30
|
+
/**
|
|
31
|
+
* Convert text styles into CSS variables for both desktop and mobile.
|
|
32
|
+
*/
|
|
33
|
+
export declare const toTextStyleVar: (prefix: string | undefined, textStyles: TextStyles) => string;
|
|
34
|
+
/**
|
|
35
|
+
* Generates CSS variables for the spacing system.
|
|
36
|
+
*/
|
|
37
|
+
export declare const toSpacingVars: (prefix: string | undefined, spacing: Spacing) => string;
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { DEFAULT_FORM_COLORS, DEFAULT_INFO_COLORS, FormColorsToBrandingAppearanceMapping, InfoColorsToBrandingAppearanceMapping, } from "./colors";
|
|
2
|
+
import { DefaultShape, PillsShape, RectangularShape, RoundedShape, } from "./shapes";
|
|
3
|
+
import { DEFAULT_FONT_FAMILY } from "./text";
|
|
4
|
+
const hexToRGB = (color) => {
|
|
5
|
+
if (color.length == 7)
|
|
6
|
+
return {
|
|
7
|
+
r: parseInt(color.slice(1, 3), 16),
|
|
8
|
+
g: parseInt(color.slice(3, 5), 16),
|
|
9
|
+
b: parseInt(color.slice(5, 7), 16),
|
|
10
|
+
};
|
|
11
|
+
if (color.length == 4)
|
|
12
|
+
return {
|
|
13
|
+
r: parseInt(color[1], 16),
|
|
14
|
+
g: parseInt(color[2], 16),
|
|
15
|
+
b: parseInt(color[3], 16),
|
|
16
|
+
};
|
|
17
|
+
return null;
|
|
18
|
+
};
|
|
19
|
+
const isLightColor = ({ r, g, b, luminanceThreshold, }) => {
|
|
20
|
+
// Gamma correction
|
|
21
|
+
const gammaCorrect = (color) => {
|
|
22
|
+
color = color / 255;
|
|
23
|
+
return color <= 0.03928
|
|
24
|
+
? color / 12.92
|
|
25
|
+
: Math.pow((color + 0.055) / 1.055, 2.4);
|
|
26
|
+
};
|
|
27
|
+
// Calculate relative luminance with gamma correction
|
|
28
|
+
const luminance = 0.2126 * gammaCorrect(r) +
|
|
29
|
+
0.7152 * gammaCorrect(g) +
|
|
30
|
+
0.0722 * gammaCorrect(b);
|
|
31
|
+
// Return whether the background is light
|
|
32
|
+
return luminance > luminanceThreshold;
|
|
33
|
+
};
|
|
34
|
+
export const DEFAULT_LUMINANCE_THRESHOLD = 0.37;
|
|
35
|
+
const rgbToTextColors = (rgb, luminanceThreshold = DEFAULT_LUMINANCE_THRESHOLD) => {
|
|
36
|
+
const baseColor = isLightColor({ ...rgb, luminanceThreshold })
|
|
37
|
+
? "0,0,0"
|
|
38
|
+
: "255,255,255";
|
|
39
|
+
return {
|
|
40
|
+
"grey-text-dark": `rgb(${baseColor})`,
|
|
41
|
+
"grey-text-light": `rgba(${baseColor},0.70)`,
|
|
42
|
+
"grey-ui-dark": `rgba(${baseColor},0.3)`,
|
|
43
|
+
"grey-ui-light": `rgba(${baseColor},0.1)`,
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
function overlayColor(baseColor, overlay, alpha) {
|
|
47
|
+
const base = hexToRGB(baseColor) || { r: 0, g: 0, b: 0 };
|
|
48
|
+
const over = hexToRGB(overlay) || { r: 255, g: 255, b: 255 };
|
|
49
|
+
const r = Math.round(over.r * alpha + base.r * (1 - alpha));
|
|
50
|
+
const g = Math.round(over.g * alpha + base.g * (1 - alpha));
|
|
51
|
+
const b = Math.round(over.b * alpha + base.b * (1 - alpha));
|
|
52
|
+
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Applies an alpha value to a color.
|
|
56
|
+
* If the base color is light, the overlay color is black.
|
|
57
|
+
* If the base color is dark, the overlay color is white.
|
|
58
|
+
*/
|
|
59
|
+
export function applyAlpha(baseColor, alpha) {
|
|
60
|
+
const defaultRgb = { r: 255, g: 255, b: 255 };
|
|
61
|
+
const normalizedAlpha = Math.max(0, Math.min(1, alpha));
|
|
62
|
+
let appliedBaseColor = baseColor;
|
|
63
|
+
let baseRgb = hexToRGB(baseColor) || defaultRgb;
|
|
64
|
+
if (isNaN(baseRgb.r) || isNaN(baseRgb.g) || isNaN(baseRgb.b)) {
|
|
65
|
+
baseRgb = defaultRgb;
|
|
66
|
+
appliedBaseColor = "#FFFFFF";
|
|
67
|
+
}
|
|
68
|
+
const baseIsLight = isLightColor({
|
|
69
|
+
...baseRgb,
|
|
70
|
+
luminanceThreshold: DEFAULT_LUMINANCE_THRESHOLD,
|
|
71
|
+
});
|
|
72
|
+
const overlay = baseIsLight ? "#000000" : "#FFFFFF";
|
|
73
|
+
return overlayColor(appliedBaseColor, overlay, normalizedAlpha);
|
|
74
|
+
}
|
|
75
|
+
function toHex(val) {
|
|
76
|
+
return val.toString(16).padStart(2, "0").toUpperCase();
|
|
77
|
+
}
|
|
78
|
+
const textColorsForBackground = (backgroundColor, primaryColor, defaultColors, luminanceThreshold = DEFAULT_LUMINANCE_THRESHOLD) => {
|
|
79
|
+
const textColors = {
|
|
80
|
+
"grey-text-dark": defaultColors["grey-text-dark"],
|
|
81
|
+
"grey-text-light": defaultColors["grey-text-light"],
|
|
82
|
+
"grey-ui-dark": defaultColors["grey-ui-dark"],
|
|
83
|
+
"grey-ui-light": defaultColors["grey-ui-light"],
|
|
84
|
+
"primary-text": defaultColors["primary-text"],
|
|
85
|
+
};
|
|
86
|
+
// Find the text colors for the background
|
|
87
|
+
if (backgroundColor?.startsWith("#")) {
|
|
88
|
+
const rgb = hexToRGB(backgroundColor);
|
|
89
|
+
if (rgb !== null) {
|
|
90
|
+
Object.assign(textColors, rgbToTextColors(rgb));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Find the text color for the primary color
|
|
94
|
+
if (primaryColor?.startsWith("#")) {
|
|
95
|
+
const rgb = hexToRGB(primaryColor);
|
|
96
|
+
if (rgb !== null) {
|
|
97
|
+
textColors["primary-text"] = isLightColor({ ...rgb, luminanceThreshold })
|
|
98
|
+
? "black"
|
|
99
|
+
: "white";
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return textColors;
|
|
103
|
+
};
|
|
104
|
+
const colorsForButtonStates = (primaryColor) => {
|
|
105
|
+
return {
|
|
106
|
+
"primary-hover": applyAlpha(primaryColor, 0.1),
|
|
107
|
+
"primary-pressed": applyAlpha(primaryColor, 0.15),
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
const fallback = (somethingNullable, defaultValue) => {
|
|
111
|
+
return somethingNullable ? somethingNullable : defaultValue;
|
|
112
|
+
};
|
|
113
|
+
const mapColors = (colorsMapping, defaultColors, brandingAppearance) => {
|
|
114
|
+
const mappedColors = Object.entries(colorsMapping).map(([target, source]) => [
|
|
115
|
+
target,
|
|
116
|
+
fallback(brandingAppearance
|
|
117
|
+
? brandingAppearance[source]
|
|
118
|
+
: null, defaultColors[target]),
|
|
119
|
+
]);
|
|
120
|
+
return Object.fromEntries(mappedColors);
|
|
121
|
+
};
|
|
122
|
+
export const toColors = (colorsMapping, defaultColors, brandingAppearance) => {
|
|
123
|
+
const mappedColors = mapColors(colorsMapping, defaultColors, brandingAppearance);
|
|
124
|
+
return brandingAppearance
|
|
125
|
+
? {
|
|
126
|
+
...defaultColors,
|
|
127
|
+
...mappedColors,
|
|
128
|
+
...textColorsForBackground(mappedColors.background, mappedColors.primary, defaultColors),
|
|
129
|
+
...colorsForButtonStates(mappedColors.primary),
|
|
130
|
+
}
|
|
131
|
+
: { ...defaultColors }; //copy, do not reference.
|
|
132
|
+
};
|
|
133
|
+
export const toProductInfoColors = (brandingAppearance) => {
|
|
134
|
+
return toColors(InfoColorsToBrandingAppearanceMapping, DEFAULT_INFO_COLORS, brandingAppearance);
|
|
135
|
+
};
|
|
136
|
+
export const toFormColors = (brandingAppearance) => {
|
|
137
|
+
return toColors(FormColorsToBrandingAppearanceMapping, DEFAULT_FORM_COLORS, brandingAppearance);
|
|
138
|
+
};
|
|
139
|
+
export const toShape = (brandingAppearance) => {
|
|
140
|
+
if (!brandingAppearance) {
|
|
141
|
+
return DefaultShape;
|
|
142
|
+
}
|
|
143
|
+
switch (brandingAppearance.shapes) {
|
|
144
|
+
case "rounded":
|
|
145
|
+
return RoundedShape;
|
|
146
|
+
case "rectangle":
|
|
147
|
+
return RectangularShape;
|
|
148
|
+
case "pill":
|
|
149
|
+
return PillsShape;
|
|
150
|
+
default:
|
|
151
|
+
return DefaultShape;
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
export const toStyleVar = (prefix = "", entries) => entries.map(([key, value]) => `--rc-${prefix}-${key}: ${value}`).join("; ");
|
|
155
|
+
/**
|
|
156
|
+
* Assigns values to the css variables given the branding appearance customization.
|
|
157
|
+
* @param appearance BrandingAppearance
|
|
158
|
+
* @return a style parameter compatible string.
|
|
159
|
+
*/
|
|
160
|
+
export const toProductInfoStyleVar = (appearance) => {
|
|
161
|
+
const colorVariablesString = toStyleVar("color", Object.entries(toProductInfoColors(appearance)));
|
|
162
|
+
const shapeVariableString = toStyleVar("shape", Object.entries(toShape(appearance)));
|
|
163
|
+
return [colorVariablesString, shapeVariableString].join("; ");
|
|
164
|
+
};
|
|
165
|
+
/**
|
|
166
|
+
* Assigns values to the css variables given the branding appearance customization.
|
|
167
|
+
* @param appearance BrandingAppearance
|
|
168
|
+
* @return a style parameter compatible string.
|
|
169
|
+
*/
|
|
170
|
+
export const toFormStyleVar = (appearance) => {
|
|
171
|
+
const colorVariablesString = toStyleVar("color", Object.entries(toFormColors(appearance)));
|
|
172
|
+
const shapeVariableString = toStyleVar("shape", Object.entries(toShape(appearance)));
|
|
173
|
+
return [colorVariablesString, shapeVariableString].join("; ");
|
|
174
|
+
};
|
|
175
|
+
/**
|
|
176
|
+
* Convert text styles into CSS variables for both desktop and mobile.
|
|
177
|
+
*/
|
|
178
|
+
export const toTextStyleVar = (prefix = "", textStyles) => Object.entries(textStyles)
|
|
179
|
+
.flatMap(([key, { desktop, mobile }]) => [
|
|
180
|
+
`--rc-${prefix}-${key}-desktop: normal normal ${desktop.fontWeight} ${desktop.fontSize}/${desktop.lineHeight} ${DEFAULT_FONT_FAMILY}`,
|
|
181
|
+
`--rc-${prefix}-${key}-mobile: normal normal ${mobile.fontWeight} ${mobile.fontSize}/${mobile.lineHeight} ${DEFAULT_FONT_FAMILY}`,
|
|
182
|
+
`--rc-${prefix}-${key}-desktop-font-size: ${desktop.fontSize}`,
|
|
183
|
+
`--rc-${prefix}-${key}-mobile-font-size: ${mobile.fontSize}`,
|
|
184
|
+
])
|
|
185
|
+
.join("; ");
|
|
186
|
+
/**
|
|
187
|
+
* Generates CSS variables for the spacing system.
|
|
188
|
+
*/
|
|
189
|
+
export const toSpacingVars = (prefix = "", spacing) => Object.entries(spacing)
|
|
190
|
+
.map(([key, { mobile, desktop }]) => `--rc-${prefix}-${key}-mobile: ${mobile}; --rc-${prefix}-${key}-desktop: ${desktop};`)
|
|
191
|
+
.join(" ");
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @public
|
|
3
|
+
* `BrandingAppearance` defines the appearance settings
|
|
4
|
+
* of an app's branding configuration.
|
|
5
|
+
*/
|
|
6
|
+
export interface BrandingAppearance {
|
|
7
|
+
color_buttons_primary: string;
|
|
8
|
+
color_accent: string;
|
|
9
|
+
color_error: string;
|
|
10
|
+
color_product_info_bg: string;
|
|
11
|
+
color_form_bg: string;
|
|
12
|
+
color_page_bg: string;
|
|
13
|
+
font: string;
|
|
14
|
+
shapes: "default" | "rectangle" | "rounded" | "pill";
|
|
15
|
+
show_product_description: boolean;
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
export let size: "small" | "medium" | "large" = "medium";
|
|
3
|
+
|
|
4
|
+
const sizeMap = {
|
|
5
|
+
small: { width: "8px", offset: "10px" },
|
|
6
|
+
medium: { width: "12px", offset: "20px" },
|
|
7
|
+
large: { width: "16px", offset: "30px" },
|
|
8
|
+
};
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<div
|
|
12
|
+
class="rcb-processing"
|
|
13
|
+
style="--shadow-offset: {sizeMap[size].offset}; --width: {sizeMap[size]
|
|
14
|
+
.width};"
|
|
15
|
+
></div>
|
|
16
|
+
|
|
17
|
+
<style>
|
|
18
|
+
.rcb-processing {
|
|
19
|
+
width: var(--width, 12px);
|
|
20
|
+
aspect-ratio: 1;
|
|
21
|
+
border-radius: 50%;
|
|
22
|
+
animation: l5 1.5s infinite linear;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@keyframes l5 {
|
|
26
|
+
0% {
|
|
27
|
+
box-shadow:
|
|
28
|
+
var(--shadow-offset) 0 #fff2,
|
|
29
|
+
calc(-1 * var(--shadow-offset)) 0 #fff2;
|
|
30
|
+
background: #fff2;
|
|
31
|
+
}
|
|
32
|
+
25% {
|
|
33
|
+
box-shadow:
|
|
34
|
+
var(--shadow-offset) 0 #fff2,
|
|
35
|
+
calc(-1 * var(--shadow-offset)) 0 #ffff;
|
|
36
|
+
background: #fff2;
|
|
37
|
+
}
|
|
38
|
+
50% {
|
|
39
|
+
box-shadow:
|
|
40
|
+
var(--shadow-offset) 0 #fff2,
|
|
41
|
+
calc(-1 * var(--shadow-offset)) 0 #fff2;
|
|
42
|
+
background: #ffff;
|
|
43
|
+
}
|
|
44
|
+
75% {
|
|
45
|
+
box-shadow:
|
|
46
|
+
var(--shadow-offset) 0 #ffff,
|
|
47
|
+
calc(-1 * var(--shadow-offset)) 0 #fff2;
|
|
48
|
+
background: #fff2;
|
|
49
|
+
}
|
|
50
|
+
100% {
|
|
51
|
+
box-shadow:
|
|
52
|
+
var(--shadow-offset) 0 #fff2,
|
|
53
|
+
calc(-1 * var(--shadow-offset)) 0 #fff2;
|
|
54
|
+
background: #fff2;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
</style>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
+
$$bindings?: Bindings;
|
|
4
|
+
} & Exports;
|
|
5
|
+
(internal: unknown, props: Props & {
|
|
6
|
+
$$events?: Events;
|
|
7
|
+
$$slots?: Slots;
|
|
8
|
+
}): Exports & {
|
|
9
|
+
$set?: any;
|
|
10
|
+
$on?: any;
|
|
11
|
+
};
|
|
12
|
+
z_$$bindings?: Bindings;
|
|
13
|
+
}
|
|
14
|
+
declare const ProcessingAnimation: $$__sveltets_2_IsomorphicComponent<{
|
|
15
|
+
size?: "small" | "medium" | "large";
|
|
16
|
+
}, {
|
|
17
|
+
[evt: string]: CustomEvent<any>;
|
|
18
|
+
}, {}, {}, string>;
|
|
19
|
+
type ProcessingAnimation = InstanceType<typeof ProcessingAnimation>;
|
|
20
|
+
export default ProcessingAnimation;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DEFAULT_COLOR_MODE, DEFAULT_TEXT_COLOR, } from "./constants.js";
|
|
1
2
|
import { FontSizes, FontSizeTags, FontWeights, StackAlignment, StackDirection, StackDistribution, TextAlignments, } from "../types.js";
|
|
2
3
|
/**
|
|
3
4
|
* Generates CSS spacing styles for margin or padding
|
|
@@ -35,10 +36,10 @@ export function getTextComponentTag(fontSize) {
|
|
|
35
36
|
* @param params - Object containing color map, mode and fallback color
|
|
36
37
|
* @returns Color value as string
|
|
37
38
|
*/
|
|
38
|
-
export function getColor({ colorMap, colorMode =
|
|
39
|
+
export function getColor({ colorMap, colorMode = DEFAULT_COLOR_MODE, fallback = "FFFFFF", }) {
|
|
39
40
|
if (!colorMap)
|
|
40
41
|
return fallback;
|
|
41
|
-
const color = colorMap[colorMode] || colorMap[
|
|
42
|
+
const color = colorMap[colorMode] || colorMap[DEFAULT_COLOR_MODE];
|
|
42
43
|
let colorPoints = "";
|
|
43
44
|
switch (color.type) {
|
|
44
45
|
case "hex":
|
|
@@ -64,7 +65,7 @@ export function getColor({ colorMap, colorMode = "light", fallback = "FFFFFF", }
|
|
|
64
65
|
* @param colorMode - Color mode (light/dark)
|
|
65
66
|
* @returns CSS border style string
|
|
66
67
|
*/
|
|
67
|
-
export function getBorderStyle(border, colorMode =
|
|
68
|
+
export function getBorderStyle(border, colorMode = DEFAULT_COLOR_MODE) {
|
|
68
69
|
if (!border)
|
|
69
70
|
return "";
|
|
70
71
|
const color = getColor({ colorMap: border.color, colorMode });
|
|
@@ -88,7 +89,7 @@ export function getCornerRadiusStyle(corners) {
|
|
|
88
89
|
* @param params - Component style configuration object
|
|
89
90
|
* @returns CSS style object with component styles
|
|
90
91
|
*/
|
|
91
|
-
export function getComponentStyles({ background_color, border, margin, padding, color, colorMode =
|
|
92
|
+
export function getComponentStyles({ background_color, border, margin, padding, color, colorMode = DEFAULT_COLOR_MODE, shape, shadow, }) {
|
|
92
93
|
const stylesObject = {
|
|
93
94
|
"--margin-block-start": "0px",
|
|
94
95
|
"--margin-inline-end": "0px",
|
|
@@ -124,7 +125,7 @@ export function getComponentStyles({ background_color, border, margin, padding,
|
|
|
124
125
|
stylesObject["--text-color"] = getColor({
|
|
125
126
|
colorMap: color,
|
|
126
127
|
colorMode,
|
|
127
|
-
fallback:
|
|
128
|
+
fallback: DEFAULT_TEXT_COLOR,
|
|
128
129
|
});
|
|
129
130
|
}
|
|
130
131
|
if (border) {
|
|
@@ -143,7 +144,7 @@ export function getComponentStyles({ background_color, border, margin, padding,
|
|
|
143
144
|
}
|
|
144
145
|
if (shadow) {
|
|
145
146
|
stylesObject["--shadow"] = `${shadow.x}px ${shadow.y}px ${shadow.radius}px
|
|
146
|
-
${getColor({ colorMap: shadow.color, colorMode, fallback:
|
|
147
|
+
${getColor({ colorMap: shadow.color, colorMode, fallback: DEFAULT_TEXT_COLOR })}`;
|
|
147
148
|
}
|
|
148
149
|
return stylesObject;
|
|
149
150
|
}
|
|
@@ -256,7 +257,7 @@ export function getDimensionStyle(dimension) {
|
|
|
256
257
|
* @param colorMode - The currently selected ColorMode (dark/light)
|
|
257
258
|
* @returns CSS style object with text formatting properties
|
|
258
259
|
*/
|
|
259
|
-
export function getTextStyles(props, colorMode =
|
|
260
|
+
export function getTextStyles(props, colorMode = DEFAULT_COLOR_MODE) {
|
|
260
261
|
const { font_size, horizontal_alignment, font_weight, font_name, color } = props;
|
|
261
262
|
const styles = {
|
|
262
263
|
"--text-align": "initial",
|
|
@@ -404,7 +405,7 @@ export function getLinearGradientAngle(props) {
|
|
|
404
405
|
return { x1: "0%", y1: "0%", x2: "0%", y2: "0%" };
|
|
405
406
|
}
|
|
406
407
|
const { color_overlay: colorOverlay } = props;
|
|
407
|
-
const angle = colorOverlay?.[
|
|
408
|
+
const angle = colorOverlay?.[DEFAULT_COLOR_MODE]?.degrees || 0;
|
|
408
409
|
const x1 = "50%";
|
|
409
410
|
const y1 = "0%";
|
|
410
411
|
const x2 = `${Math.round(50 + Math.sin(((angle + 90) * Math.PI) / 90) * 50)}%`;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@revenuecat/purchases-ui-js",
|
|
3
3
|
"description": "Web components for Paywalls. Powered by RevenueCat",
|
|
4
4
|
"private": false,
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.1.21",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "RevenueCat, Inc."
|
|
8
8
|
},
|
|
@@ -61,37 +61,37 @@
|
|
|
61
61
|
"svelte": "^5.3.0"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
|
-
"@chromatic-com/storybook": "^3.2.
|
|
65
|
-
"@eslint/js": "^9.
|
|
66
|
-
"@storybook/addon-essentials": "^8.
|
|
67
|
-
"@storybook/addon-interactions": "^8.
|
|
68
|
-
"@storybook/addon-links": "^8.
|
|
64
|
+
"@chromatic-com/storybook": "^3.2.3",
|
|
65
|
+
"@eslint/js": "^9.18.0",
|
|
66
|
+
"@storybook/addon-essentials": "^8.5.0",
|
|
67
|
+
"@storybook/addon-interactions": "^8.5.0",
|
|
68
|
+
"@storybook/addon-links": "^8.5.0",
|
|
69
69
|
"@storybook/addon-svelte-csf": "^5.0.0-next.14",
|
|
70
|
-
"@storybook/blocks": "^8.
|
|
71
|
-
"@storybook/svelte": "^8.
|
|
72
|
-
"@storybook/sveltekit": "^8.
|
|
73
|
-
"@storybook/test": "^8.
|
|
74
|
-
"@sveltejs/adapter-node": "^5.2.
|
|
75
|
-
"@sveltejs/kit": "^2.
|
|
70
|
+
"@storybook/blocks": "^8.5.0",
|
|
71
|
+
"@storybook/svelte": "^8.5.0",
|
|
72
|
+
"@storybook/sveltekit": "^8.5.0",
|
|
73
|
+
"@storybook/test": "^8.5.0",
|
|
74
|
+
"@sveltejs/adapter-node": "^5.2.11",
|
|
75
|
+
"@sveltejs/kit": "^2.15.3",
|
|
76
76
|
"@sveltejs/package": "^2.3.7",
|
|
77
|
-
"@sveltejs/vite-plugin-svelte": "^5.0.
|
|
78
|
-
"@typescript-eslint/parser": "^8.
|
|
79
|
-
"chromatic": "^11.
|
|
80
|
-
"eslint": "^9.
|
|
77
|
+
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
|
78
|
+
"@typescript-eslint/parser": "^8.20.0",
|
|
79
|
+
"chromatic": "^11.24.0",
|
|
80
|
+
"eslint": "^9.18.0",
|
|
81
81
|
"eslint-plugin-svelte": "^2.46.1",
|
|
82
|
-
"globals": "^15.
|
|
82
|
+
"globals": "^15.14.0",
|
|
83
83
|
"husky": "^9.1.7",
|
|
84
|
-
"jsdom": "^
|
|
85
|
-
"lint-staged": "^15.
|
|
84
|
+
"jsdom": "^26.0.0",
|
|
85
|
+
"lint-staged": "^15.3.0",
|
|
86
86
|
"prettier": "^3.4.2",
|
|
87
|
-
"prettier-plugin-svelte": "^3.3.
|
|
87
|
+
"prettier-plugin-svelte": "^3.3.3",
|
|
88
88
|
"publint": "^0.2.12",
|
|
89
|
-
"storybook": "^8.
|
|
90
|
-
"svelte": "^5.
|
|
91
|
-
"svelte-check": "^4.1.
|
|
92
|
-
"typescript": "^5.7.
|
|
93
|
-
"typescript-eslint": "^8.
|
|
94
|
-
"vite": "^6.0.
|
|
89
|
+
"storybook": "^8.5.0",
|
|
90
|
+
"svelte": "^5.18.0",
|
|
91
|
+
"svelte-check": "^4.1.4",
|
|
92
|
+
"typescript": "^5.7.3",
|
|
93
|
+
"typescript-eslint": "^8.20.0",
|
|
94
|
+
"vite": "^6.0.7",
|
|
95
95
|
"vitest": "^2.1.8"
|
|
96
96
|
},
|
|
97
97
|
"lint-staged": {
|