@revenuecat/purchases-ui-js
Version:
Web components for Paywalls. Powered by RevenueCat
141 lines (140 loc) • 4.17 kB
JavaScript
import { DEFAULT_SPACING } from "./constants";
export function css(props) {
return Object.entries(props)
.map(([key, value]) => `${key}:${value}`)
.join(";");
}
export function px(value) {
return `${value}px`;
}
function mapTuple(...tuple) {
return tuple.map(px).join(" ");
}
export function mapColorMode(colorMode, value) {
const result = value[colorMode];
return result ?? value.light;
}
export function mapSize(size) {
switch (size.type) {
case "fill":
// Support both webkit and mozilla browsers
if (navigator.userAgent.includes("Firefox")) {
return "-moz-available";
}
else {
return "-webkit-fill-available";
}
case "fit":
return "fit-content";
case "fixed":
return px(size.value);
case "relative": {
return `${size.value * 100}%`;
}
}
}
export function mapSpacing(spacing) {
const { top, bottom, leading, trailing } = spacing ?? DEFAULT_SPACING;
return mapTuple(top, trailing, bottom, leading);
}
export function mapColorInfo(info) {
if (info.type === "alias" || info.type === "hex") {
return info.value;
}
const points = info.points
.map((point) => `${point.color} ${point.percent}%`)
.join(", ");
switch (info.type) {
case "linear":
return `linear-gradient(${info.degrees}deg, ${points})`;
case "radial":
return `radial-gradient(circle, ${points})`;
}
}
export function mapColor(colorMode, scheme) {
if (scheme == null) {
return "transparent";
}
const info = mapColorMode(colorMode, scheme);
return mapColorInfo(info);
}
export function mapOverlay(colorMode, colorOverlay) {
if (colorOverlay == null) {
return "transparent";
}
return mapColor(colorMode, colorOverlay);
}
/**
* Maps border props to inline CSS.
*
* For gradient borders, this returns CSS custom properties consumed by a
* global `::after` rule (defined in Paywall.svelte). Any element that
* receives these styles **must** also have the `rc-gradient-border` class
* for the pseudo-element to render.
*/
export function mapBorder(colorMode, border) {
const resetVars = {
"--rc-border-display": "none",
"--rc-border-bg": "transparent",
"--rc-border-width": "0px",
};
if (border == null) {
return {
border: "none",
...resetVars,
};
}
const { width } = border;
const info = mapColorMode(colorMode, border.color);
const color = mapColorInfo(info);
if (info.type === "alias" || info.type === "hex") {
return {
border: `${width}px solid ${color}`,
...resetVars,
};
}
// For gradient borders, set CSS custom properties for the ::after pseudo-element.
// Keep transparent border to preserve layout space in box model.
return {
border: `${width}px solid transparent`,
"--rc-border-display": "block",
"--rc-border-bg": color,
"--rc-border-width": `${width}px`,
};
}
function mapCornerRadius(corners) {
if (corners == null) {
return "0";
}
const { top_leading, top_trailing, bottom_trailing, bottom_leading } = corners;
return mapTuple(top_leading, top_trailing, bottom_trailing, bottom_leading);
}
export function mapBorderRadius(shape) {
switch (shape?.type) {
case undefined:
case "concave":
case "convex":
return "0";
case "rectangle":
return `${mapCornerRadius(shape.corners)}`;
case "circle":
case "pill":
return "9999px";
}
}
export function mapShadow(colorMode, shadow) {
if (shadow == null) {
return "none";
}
const { x, y, radius } = shadow;
const color = mapColor(colorMode, shadow.color);
return `${x}px ${y}px ${radius}px ${color}`;
}
export function mapFitMode(fit_mode) {
switch (fit_mode) {
case "fill":
return "cover";
case "fit":
return "contain";
}
}