(sdk) allow passing a background color to the calendar iframe

Let integrators pass a custom background color to the iframe used by
the calendar SDK, so it can match the surrounding product's theme.
This commit is contained in:
lebaudantoine
2026-08-03 20:46:25 +02:00
committed by aleb_the_flash
parent b593516802
commit f49c61d9bf
2 changed files with 51 additions and 13 deletions
+1
View File
@@ -18,6 +18,7 @@ and this project adheres to
- ✨(frontend) let users set default configuration for generated links
- ✨(frontend) expose media state to external gateways
- ✨(frontend) add connection test feature
- ✨(sdk) allow passing a background color to the calendar iframe
### Changed
@@ -43,6 +43,34 @@ const CreateMeetingButton = () => {
if (room?.slug) return getRouteUrl('room', room.slug)
}, [room])
const backgroundColor = useMemo(() => {
const param = searchParams.get('backgroundColor')
if (!param) return 'transparent'
const value = param.trim()
// Allow raw hex passed without '#' (e.g. ?backgroundColor=ff0000)
if (
/^[0-9a-fA-F]{3}$|^[0-9a-fA-F]{4}$|^[0-9a-fA-F]{6}$|^[0-9a-fA-F]{8}$/.test(
value
)
) {
return `#${value}`
}
// Already-valid hex (e.g. URL-encoded %23ff0000 → '#ff0000')
if (/^#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(value)) {
return value
}
// Fallback: only allow simple named colors, block anything injectable
if (/^[a-zA-Z]+$/.test(value)) {
return value
}
return 'transparent'
}, [searchParams])
useEffect(() => {
if (!data?.room?.slug) return
setRoom(data.room)
@@ -78,20 +106,27 @@ const CreateMeetingButton = () => {
if (isPending) {
return (
<div
className={css({
display: 'flex',
alignItems: 'center',
gap: '0.5rem',
})}
style={{
backgroundColor: backgroundColor,
height: '100%',
}}
>
<Spinner size={34} />
<Button
variant="quaternaryText"
square
icon={<RiCloseLine />}
onPress={resetState}
aria-label={t('resetLabel')}
/>
<div
className={css({
display: 'flex',
alignItems: 'center',
gap: '0.5rem',
})}
>
<Spinner size={34} />
<Button
variant="quaternaryText"
square
icon={<RiCloseLine />}
onPress={resetState}
aria-label={t('resetLabel')}
/>
</div>
</div>
)
}
@@ -104,6 +139,8 @@ const CreateMeetingButton = () => {
justifyContent: 'start',
alignItems: 'start',
border: 'none',
backgroundColor: backgroundColor,
height: '100%',
}}
>
{roomUrl && room?.slug ? (