@revenuecat/purchases-ui-js 0.0.21 → 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.svelte +7 -5
- package/dist/components/paywall/Paywall.svelte +0 -7
- package/dist/components/purchase-button/PurchaseButton.svelte +3 -3
- 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/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/package.json +1 -1
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* All text styles get translated into --rc-text-<property_name> CSS variables.
|
|
3
|
+
* i.e., --rc-text-title1-font-size or --rc-text-title1-line-height
|
|
4
|
+
*/
|
|
5
|
+
export const DEFAULT_FONT_FAMILY = "-apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif";
|
|
6
|
+
const FONT_WEIGHTS = {
|
|
7
|
+
regular: "400",
|
|
8
|
+
medium: "500",
|
|
9
|
+
semibold: "600",
|
|
10
|
+
};
|
|
11
|
+
const FONT_SIZES = {
|
|
12
|
+
"10": "10px",
|
|
13
|
+
"12": "12px",
|
|
14
|
+
"14": "14px",
|
|
15
|
+
"16": "16px",
|
|
16
|
+
"18": "18px",
|
|
17
|
+
"20": "20px",
|
|
18
|
+
"24": "24px",
|
|
19
|
+
"28": "28px",
|
|
20
|
+
"32": "32px",
|
|
21
|
+
"36": "36px",
|
|
22
|
+
"40": "40px",
|
|
23
|
+
};
|
|
24
|
+
const LINE_HEIGHTS = {
|
|
25
|
+
"120": "120%",
|
|
26
|
+
"130": "130%",
|
|
27
|
+
"140": "140%",
|
|
28
|
+
};
|
|
29
|
+
const LETTER_SPACING = {
|
|
30
|
+
tight: "0.20%",
|
|
31
|
+
regular: "0",
|
|
32
|
+
loose: "0.20%",
|
|
33
|
+
};
|
|
34
|
+
const MOBILE_TEXT_STYLES = {
|
|
35
|
+
heading2xl: {
|
|
36
|
+
fontSize: FONT_SIZES["28"],
|
|
37
|
+
lineHeight: LINE_HEIGHTS["120"],
|
|
38
|
+
fontWeight: FONT_WEIGHTS["semibold"],
|
|
39
|
+
letterSpacing: LETTER_SPACING["tight"],
|
|
40
|
+
},
|
|
41
|
+
headingXl: {
|
|
42
|
+
fontSize: FONT_SIZES["24"],
|
|
43
|
+
lineHeight: LINE_HEIGHTS["130"],
|
|
44
|
+
fontWeight: FONT_WEIGHTS["semibold"],
|
|
45
|
+
letterSpacing: LETTER_SPACING["regular"],
|
|
46
|
+
},
|
|
47
|
+
headingLg: {
|
|
48
|
+
fontSize: "20px",
|
|
49
|
+
lineHeight: LINE_HEIGHTS["130"],
|
|
50
|
+
fontWeight: FONT_WEIGHTS["semibold"],
|
|
51
|
+
letterSpacing: LETTER_SPACING["regular"],
|
|
52
|
+
},
|
|
53
|
+
headingMd: {
|
|
54
|
+
fontSize: "16px",
|
|
55
|
+
lineHeight: LINE_HEIGHTS["140"],
|
|
56
|
+
fontWeight: FONT_WEIGHTS["medium"],
|
|
57
|
+
letterSpacing: LETTER_SPACING["regular"],
|
|
58
|
+
},
|
|
59
|
+
bodyBase: {
|
|
60
|
+
fontSize: FONT_SIZES["16"],
|
|
61
|
+
lineHeight: LINE_HEIGHTS["140"],
|
|
62
|
+
fontWeight: FONT_WEIGHTS["regular"],
|
|
63
|
+
letterSpacing: LETTER_SPACING["regular"],
|
|
64
|
+
},
|
|
65
|
+
bodySmall: {
|
|
66
|
+
fontSize: FONT_SIZES["14"],
|
|
67
|
+
lineHeight: LINE_HEIGHTS["140"],
|
|
68
|
+
fontWeight: FONT_WEIGHTS["regular"],
|
|
69
|
+
letterSpacing: LETTER_SPACING["regular"],
|
|
70
|
+
},
|
|
71
|
+
labelButton: {
|
|
72
|
+
fontSize: FONT_SIZES["16"],
|
|
73
|
+
lineHeight: LINE_HEIGHTS["140"],
|
|
74
|
+
fontWeight: FONT_WEIGHTS["regular"],
|
|
75
|
+
letterSpacing: LETTER_SPACING["tight"],
|
|
76
|
+
},
|
|
77
|
+
labelDefault: {
|
|
78
|
+
fontSize: FONT_SIZES["14"],
|
|
79
|
+
lineHeight: LINE_HEIGHTS["140"],
|
|
80
|
+
fontWeight: FONT_WEIGHTS["regular"],
|
|
81
|
+
letterSpacing: LETTER_SPACING["tight"],
|
|
82
|
+
},
|
|
83
|
+
captionDefault: {
|
|
84
|
+
fontSize: FONT_SIZES["12"],
|
|
85
|
+
lineHeight: LINE_HEIGHTS["140"],
|
|
86
|
+
fontWeight: FONT_WEIGHTS["regular"],
|
|
87
|
+
letterSpacing: LETTER_SPACING["regular"],
|
|
88
|
+
},
|
|
89
|
+
captionLink: {
|
|
90
|
+
fontSize: FONT_SIZES["12"],
|
|
91
|
+
lineHeight: LINE_HEIGHTS["140"],
|
|
92
|
+
fontWeight: FONT_WEIGHTS["regular"],
|
|
93
|
+
letterSpacing: LETTER_SPACING["regular"],
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
const DESKTOP_TEXT_STYLES = {
|
|
97
|
+
heading2xl: {
|
|
98
|
+
...MOBILE_TEXT_STYLES.heading2xl,
|
|
99
|
+
fontSize: FONT_SIZES["36"],
|
|
100
|
+
},
|
|
101
|
+
headingXl: {
|
|
102
|
+
...MOBILE_TEXT_STYLES.headingXl,
|
|
103
|
+
fontSize: FONT_SIZES["32"],
|
|
104
|
+
},
|
|
105
|
+
headingLg: {
|
|
106
|
+
...MOBILE_TEXT_STYLES.headingLg,
|
|
107
|
+
fontSize: FONT_SIZES["24"],
|
|
108
|
+
},
|
|
109
|
+
headingMd: {
|
|
110
|
+
...MOBILE_TEXT_STYLES.headingMd,
|
|
111
|
+
fontSize: FONT_SIZES["18"],
|
|
112
|
+
},
|
|
113
|
+
bodyBase: {
|
|
114
|
+
...MOBILE_TEXT_STYLES.bodyBase,
|
|
115
|
+
},
|
|
116
|
+
bodySmall: {
|
|
117
|
+
...MOBILE_TEXT_STYLES.bodySmall,
|
|
118
|
+
},
|
|
119
|
+
labelButton: {
|
|
120
|
+
...MOBILE_TEXT_STYLES.labelButton,
|
|
121
|
+
},
|
|
122
|
+
labelDefault: {
|
|
123
|
+
...MOBILE_TEXT_STYLES.labelDefault,
|
|
124
|
+
},
|
|
125
|
+
captionDefault: {
|
|
126
|
+
...MOBILE_TEXT_STYLES.captionDefault,
|
|
127
|
+
},
|
|
128
|
+
captionLink: {
|
|
129
|
+
...MOBILE_TEXT_STYLES.captionLink,
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
export const DEFAULT_TEXT_STYLES = {
|
|
133
|
+
heading2xl: {
|
|
134
|
+
mobile: MOBILE_TEXT_STYLES.heading2xl,
|
|
135
|
+
desktop: DESKTOP_TEXT_STYLES.heading2xl,
|
|
136
|
+
},
|
|
137
|
+
headingXl: {
|
|
138
|
+
desktop: DESKTOP_TEXT_STYLES.headingXl,
|
|
139
|
+
mobile: MOBILE_TEXT_STYLES.headingXl,
|
|
140
|
+
},
|
|
141
|
+
headingLg: {
|
|
142
|
+
desktop: DESKTOP_TEXT_STYLES.headingLg,
|
|
143
|
+
mobile: MOBILE_TEXT_STYLES.headingLg,
|
|
144
|
+
},
|
|
145
|
+
headingMd: {
|
|
146
|
+
desktop: DESKTOP_TEXT_STYLES.headingMd,
|
|
147
|
+
mobile: MOBILE_TEXT_STYLES.headingMd,
|
|
148
|
+
},
|
|
149
|
+
bodyBase: {
|
|
150
|
+
desktop: DESKTOP_TEXT_STYLES.bodyBase,
|
|
151
|
+
mobile: MOBILE_TEXT_STYLES.bodyBase,
|
|
152
|
+
},
|
|
153
|
+
bodySmall: {
|
|
154
|
+
desktop: DESKTOP_TEXT_STYLES.bodySmall,
|
|
155
|
+
mobile: MOBILE_TEXT_STYLES.bodySmall,
|
|
156
|
+
},
|
|
157
|
+
labelButton: {
|
|
158
|
+
desktop: DESKTOP_TEXT_STYLES.labelButton,
|
|
159
|
+
mobile: MOBILE_TEXT_STYLES.labelButton,
|
|
160
|
+
},
|
|
161
|
+
labelDefault: {
|
|
162
|
+
desktop: DESKTOP_TEXT_STYLES.labelDefault,
|
|
163
|
+
mobile: MOBILE_TEXT_STYLES.labelDefault,
|
|
164
|
+
},
|
|
165
|
+
captionDefault: {
|
|
166
|
+
desktop: DESKTOP_TEXT_STYLES.captionDefault,
|
|
167
|
+
mobile: MOBILE_TEXT_STYLES.captionDefault,
|
|
168
|
+
},
|
|
169
|
+
captionLink: {
|
|
170
|
+
desktop: DESKTOP_TEXT_STYLES.captionLink,
|
|
171
|
+
mobile: MOBILE_TEXT_STYLES.captionLink,
|
|
172
|
+
},
|
|
173
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Shape } from "./shapes";
|
|
2
|
+
import type { Colors } from "./colors";
|
|
3
|
+
import type { BrandingAppearance } from "../utils/branding";
|
|
4
|
+
export declare class Theme {
|
|
5
|
+
private readonly brandingAppearance;
|
|
6
|
+
constructor(brandingAppearance?: BrandingAppearance | null | undefined);
|
|
7
|
+
get shape(): Shape;
|
|
8
|
+
get formColors(): Colors;
|
|
9
|
+
get formStyleVars(): string;
|
|
10
|
+
get productInfoStyleVars(): string;
|
|
11
|
+
get spacing(): import("./spacing").Spacing;
|
|
12
|
+
get textStyles(): import("./text").TextStyles;
|
|
13
|
+
get textStyleVars(): string;
|
|
14
|
+
get spacingStyleVars(): string;
|
|
15
|
+
}
|
|
@@ -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;
|