feat: support whitelabelling in the embedding (#1491)

## Description

Adds support for customising the theme and CSS for the embedding
components which is restricted to platform customers and above.

Additionally adds proper support for the platform plan which will let us
update our stripe products.

<img width="1040" alt="image"
src="https://github.com/user-attachments/assets/f694cd1e-ac93-4dc0-9f78-92fa813f6404">
<img width="1015" alt="image"
src="https://github.com/user-attachments/assets/4209972a-b2bd-40c9-9049-0367382a4de5">
<img width="1065" alt="image"
src="https://github.com/user-attachments/assets/fdbaaaa5-a028-4b1d-a58a-ea6224e21abe">


## Related Issue

N/A

## Changes Made

- Added support for using CSS Vars and CSS within the embedding route
- Added a guard for platform and enterprise plans to activate the custom
css
- Added support for the platform plan

## Testing Performed
Yes
This commit is contained in:
Lucas Smith
2024-11-25 15:47:00 +11:00
committed by GitHub
parent cd5adce7df
commit b15e1d6c47
22 changed files with 282 additions and 39 deletions

View File

@ -0,0 +1,59 @@
import { colord } from 'colord';
import { toSnakeCase } from 'remeda';
import { z } from 'zod';
export const ZCssVarsSchema = z
.object({
background: z.string().optional().describe('Base background color'),
foreground: z.string().optional().describe('Base text color'),
muted: z.string().optional().describe('Muted/subtle background color'),
mutedForeground: z.string().optional().describe('Muted/subtle text color'),
popover: z.string().optional().describe('Popover/dropdown background color'),
popoverForeground: z.string().optional().describe('Popover/dropdown text color'),
card: z.string().optional().describe('Card background color'),
cardBorder: z.string().optional().describe('Card border color'),
cardBorderTint: z.string().optional().describe('Card border tint/highlight color'),
cardForeground: z.string().optional().describe('Card text color'),
fieldCard: z.string().optional().describe('Field card background color'),
fieldCardBorder: z.string().optional().describe('Field card border color'),
fieldCardForeground: z.string().optional().describe('Field card text color'),
widget: z.string().optional().describe('Widget background color'),
widgetForeground: z.string().optional().describe('Widget text color'),
border: z.string().optional().describe('Default border color'),
input: z.string().optional().describe('Input field border color'),
primary: z.string().optional().describe('Primary action/button color'),
primaryForeground: z.string().optional().describe('Primary action/button text color'),
secondary: z.string().optional().describe('Secondary action/button color'),
secondaryForeground: z.string().optional().describe('Secondary action/button text color'),
accent: z.string().optional().describe('Accent/highlight color'),
accentForeground: z.string().optional().describe('Accent/highlight text color'),
destructive: z.string().optional().describe('Destructive/danger action color'),
destructiveForeground: z.string().optional().describe('Destructive/danger text color'),
ring: z.string().optional().describe('Focus ring color'),
radius: z.string().optional().describe('Border radius size in REM units'),
warning: z.string().optional().describe('Warning/alert color'),
})
.describe('Custom CSS variables for theming');
export type TCssVarsSchema = z.infer<typeof ZCssVarsSchema>;
export const toNativeCssVars = (vars: TCssVarsSchema) => {
const cssVars: Record<string, string> = {};
const { radius, ...colorVars } = vars;
for (const [key, value] of Object.entries(colorVars)) {
if (value) {
const color = colord(value);
const { h, s, l } = color.toHsl();
cssVars[`--${toSnakeCase(key)}`] = `${h} ${s} ${l}`;
}
}
if (radius) {
cssVars[`--radius`] = `${radius}`;
}
return cssVars;
};