mirror of
https://github.com/suitenumerique/meet.git
synced 2026-08-30 12:09:08 +00:00
✨(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:
committed by
aleb_the_flash
parent
b593516802
commit
f49c61d9bf
@@ -18,6 +18,7 @@ and this project adheres to
|
|||||||
- ✨(frontend) let users set default configuration for generated links
|
- ✨(frontend) let users set default configuration for generated links
|
||||||
- ✨(frontend) expose media state to external gateways
|
- ✨(frontend) expose media state to external gateways
|
||||||
- ✨(frontend) add connection test feature
|
- ✨(frontend) add connection test feature
|
||||||
|
- ✨(sdk) allow passing a background color to the calendar iframe
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,34 @@ const CreateMeetingButton = () => {
|
|||||||
if (room?.slug) return getRouteUrl('room', room.slug)
|
if (room?.slug) return getRouteUrl('room', room.slug)
|
||||||
}, [room])
|
}, [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(() => {
|
useEffect(() => {
|
||||||
if (!data?.room?.slug) return
|
if (!data?.room?.slug) return
|
||||||
setRoom(data.room)
|
setRoom(data.room)
|
||||||
@@ -78,20 +106,27 @@ const CreateMeetingButton = () => {
|
|||||||
if (isPending) {
|
if (isPending) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={css({
|
style={{
|
||||||
display: 'flex',
|
backgroundColor: backgroundColor,
|
||||||
alignItems: 'center',
|
height: '100%',
|
||||||
gap: '0.5rem',
|
}}
|
||||||
})}
|
|
||||||
>
|
>
|
||||||
<Spinner size={34} />
|
<div
|
||||||
<Button
|
className={css({
|
||||||
variant="quaternaryText"
|
display: 'flex',
|
||||||
square
|
alignItems: 'center',
|
||||||
icon={<RiCloseLine />}
|
gap: '0.5rem',
|
||||||
onPress={resetState}
|
})}
|
||||||
aria-label={t('resetLabel')}
|
>
|
||||||
/>
|
<Spinner size={34} />
|
||||||
|
<Button
|
||||||
|
variant="quaternaryText"
|
||||||
|
square
|
||||||
|
icon={<RiCloseLine />}
|
||||||
|
onPress={resetState}
|
||||||
|
aria-label={t('resetLabel')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -104,6 +139,8 @@ const CreateMeetingButton = () => {
|
|||||||
justifyContent: 'start',
|
justifyContent: 'start',
|
||||||
alignItems: 'start',
|
alignItems: 'start',
|
||||||
border: 'none',
|
border: 'none',
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
height: '100%',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{roomUrl && room?.slug ? (
|
{roomUrl && room?.slug ? (
|
||||||
|
|||||||
Reference in New Issue
Block a user