@@ -552,3 +552,42 @@ export const CloseIcon = (props: IconProps) => (
|
||||
<line x1="6" y1="6" x2="18" y2="18"></line>
|
||||
</Icon>
|
||||
)
|
||||
|
||||
export const NoRadiusIcon = (props: IconProps) => (
|
||||
<Icon viewBox="0 0 20 20" {...props}>
|
||||
<mask id="path-1-inside-1_1009_3" fill="white">
|
||||
<path d="M0 0H20V20H0V0Z" />
|
||||
</mask>
|
||||
<path
|
||||
d="M0 0V-2H-2V0H0ZM0 20H-2V22H0V20ZM0 2H20V-2H0V2ZM20 18H0V22H20V18ZM2 20V0H-2V20H2Z"
|
||||
fill="black"
|
||||
mask="url(#path-1-inside-1_1009_3)"
|
||||
/>
|
||||
</Icon>
|
||||
)
|
||||
|
||||
export const MediumRadiusIcon = (props: IconProps) => (
|
||||
<Icon viewBox="0 0 20 20" {...props}>
|
||||
<mask id="path-1-inside-1_1009_4" fill="white">
|
||||
<path d="M0 4C0 1.79086 1.79086 0 4 0H20V20H4C1.79086 20 0 18.2091 0 16V4Z" />
|
||||
</mask>
|
||||
<path
|
||||
d="M-2 4C-2 0.686292 0.686292 -2 4 -2H20V2H4C2.89543 2 2 2.89543 2 4H-2ZM20 22H4C0.686292 22 -2 19.3137 -2 16H2C2 17.1046 2.89543 18 4 18H20V22ZM4 22C0.686292 22 -2 19.3137 -2 16V4C-2 0.686292 0.686292 -2 4 -2V2C2.89543 2 2 2.89543 2 4V16C2 17.1046 2.89543 18 4 18V22ZM20 0V20V0Z"
|
||||
fill="black"
|
||||
mask="url(#path-1-inside-1_1009_4)"
|
||||
/>
|
||||
</Icon>
|
||||
)
|
||||
|
||||
export const LargeRadiusIcon = (props: IconProps) => (
|
||||
<Icon viewBox="0 0 20 20" {...props}>
|
||||
<mask id="path-1-inside-1_1009_5" fill="white">
|
||||
<path d="M0 10C0 4.47715 4.47715 0 10 0H20V20H10C4.47715 20 0 15.5228 0 10V10Z" />
|
||||
</mask>
|
||||
<path
|
||||
d="M-2 10C-2 3.37258 3.37258 -2 10 -2H20V2H10C5.58172 2 2 5.58172 2 10H-2ZM20 22H10C3.37258 22 -2 16.6274 -2 10H2C2 14.4183 5.58172 18 10 18H20V22ZM10 22C3.37258 22 -2 16.6274 -2 10C-2 3.37258 3.37258 -2 10 -2V2C5.58172 2 2 5.58172 2 10C2 14.4183 5.58172 18 10 18V22ZM20 0V20V0Z"
|
||||
fill="black"
|
||||
mask="url(#path-1-inside-1_1009_5)"
|
||||
/>
|
||||
</Icon>
|
||||
)
|
||||
|
||||
@@ -7,35 +7,32 @@ import {
|
||||
useRadioGroup,
|
||||
UseRadioProps,
|
||||
} from '@chakra-ui/react'
|
||||
import { BackgroundType } from '@typebot.io/schemas'
|
||||
import { ReactNode } from 'react'
|
||||
|
||||
type Props = {
|
||||
backgroundType: BackgroundType
|
||||
onBackgroundTypeChange: (type: BackgroundType) => void
|
||||
type Props<T extends string> = {
|
||||
options: (T | { value: T; label: ReactNode })[]
|
||||
defaultValue: T
|
||||
onSelect: (newValue: T) => void
|
||||
}
|
||||
export const BackgroundTypeRadioButtons = ({
|
||||
backgroundType,
|
||||
onBackgroundTypeChange,
|
||||
}: Props) => {
|
||||
const options = ['Color', 'Image', 'None']
|
||||
|
||||
export const RadioButtons = <T extends string>({
|
||||
options,
|
||||
defaultValue,
|
||||
onSelect,
|
||||
}: Props<T>) => {
|
||||
const { getRootProps, getRadioProps } = useRadioGroup({
|
||||
name: 'background-type',
|
||||
defaultValue: backgroundType,
|
||||
onChange: (nextVal: string) =>
|
||||
onBackgroundTypeChange(nextVal as BackgroundType),
|
||||
defaultValue,
|
||||
onChange: onSelect,
|
||||
})
|
||||
|
||||
const group = getRootProps()
|
||||
|
||||
return (
|
||||
<HStack {...group}>
|
||||
{options.map((value) => {
|
||||
const radio = getRadioProps({ value })
|
||||
{options.map((item) => {
|
||||
const radio = getRadioProps({ value: parseValue(item) })
|
||||
return (
|
||||
<RadioCard key={value} {...radio}>
|
||||
{value}
|
||||
<RadioCard key={parseValue(item)} {...radio}>
|
||||
{parseLabel(item)}
|
||||
</RadioCard>
|
||||
)
|
||||
})}
|
||||
@@ -76,3 +73,9 @@ export const RadioCard = (props: UseRadioProps & { children: ReactNode }) => {
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
const parseValue = (item: string | { value: string; label: ReactNode }) =>
|
||||
typeof item === 'string' ? item : item.value
|
||||
|
||||
const parseLabel = (item: string | { value: string; label: ReactNode }) =>
|
||||
typeof item === 'string' ? item : item.label
|
||||
@@ -1,3 +1,9 @@
|
||||
import {
|
||||
LargeRadiusIcon,
|
||||
MediumRadiusIcon,
|
||||
NoRadiusIcon,
|
||||
} from '@/components/icons'
|
||||
import { RadioButtons } from '@/components/inputs/RadioButtons'
|
||||
import { Heading, Stack } from '@chakra-ui/react'
|
||||
import {
|
||||
AvatarProps,
|
||||
@@ -59,6 +65,29 @@ export const ChatThemeSettings = ({
|
||||
onHostBubblesChange={handleHostBubblesChange}
|
||||
/>
|
||||
</Stack>
|
||||
<Stack borderWidth={1} rounded="md" p="4" spacing={4}>
|
||||
<Heading fontSize="lg">Corners roundness</Heading>
|
||||
<RadioButtons
|
||||
options={[
|
||||
{
|
||||
label: <NoRadiusIcon />,
|
||||
value: 'none',
|
||||
},
|
||||
{
|
||||
label: <MediumRadiusIcon />,
|
||||
value: 'medium',
|
||||
},
|
||||
{
|
||||
label: <LargeRadiusIcon />,
|
||||
value: 'large',
|
||||
},
|
||||
]}
|
||||
defaultValue={chatTheme.roundness ?? 'medium'}
|
||||
onSelect={(roundness) =>
|
||||
onChatThemeChange({ ...chatTheme, roundness })
|
||||
}
|
||||
/>
|
||||
</Stack>
|
||||
<Stack borderWidth={1} rounded="md" p="4" spacing={4}>
|
||||
<Heading fontSize="lg">User bubbles</Heading>
|
||||
<GuestBubbles
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { RadioButtons } from '@/components/inputs/RadioButtons'
|
||||
import { Stack, Text } from '@chakra-ui/react'
|
||||
import { Background, BackgroundType } from '@typebot.io/schemas'
|
||||
import React from 'react'
|
||||
import { BackgroundContent } from './BackgroundContent'
|
||||
import { BackgroundTypeRadioButtons } from './BackgroundTypeRadioButtons'
|
||||
|
||||
type Props = {
|
||||
background?: Background
|
||||
@@ -25,9 +25,14 @@ export const BackgroundSelector = ({
|
||||
return (
|
||||
<Stack spacing={4}>
|
||||
<Text>Background</Text>
|
||||
<BackgroundTypeRadioButtons
|
||||
backgroundType={background?.type ?? defaultBackgroundType}
|
||||
onBackgroundTypeChange={handleBackgroundTypeChange}
|
||||
<RadioButtons
|
||||
options={[
|
||||
BackgroundType.COLOR,
|
||||
BackgroundType.IMAGE,
|
||||
BackgroundType.NONE,
|
||||
]}
|
||||
defaultValue={background?.type ?? defaultBackgroundType}
|
||||
onSelect={handleBackgroundTypeChange}
|
||||
/>
|
||||
<BackgroundContent
|
||||
background={background}
|
||||
|
||||
@@ -90,6 +90,32 @@ test.describe.parallel('Theme page', () => {
|
||||
|
||||
await expect(page.locator('.typebot-container img')).toBeHidden()
|
||||
|
||||
// Roundness
|
||||
await expect(page.getByRole('button', { name: 'Go' })).toHaveCSS(
|
||||
'border-radius',
|
||||
'6px'
|
||||
)
|
||||
await page
|
||||
.getByRole('region', { name: 'Chat' })
|
||||
.getByRole('radiogroup')
|
||||
.locator('div')
|
||||
.first()
|
||||
.click()
|
||||
await expect(page.getByRole('button', { name: 'Go' })).toHaveCSS(
|
||||
'border-radius',
|
||||
'0px'
|
||||
)
|
||||
await page
|
||||
.getByRole('region', { name: 'Chat' })
|
||||
.getByRole('radiogroup')
|
||||
.locator('div')
|
||||
.nth(2)
|
||||
.click()
|
||||
await expect(page.getByRole('button', { name: 'Go' })).toHaveCSS(
|
||||
'border-radius',
|
||||
'20px'
|
||||
)
|
||||
|
||||
// Host bubbles
|
||||
await page.click(
|
||||
'[data-testid="host-bubbles-theme"] >> [aria-label="Pick a color"] >> nth=0'
|
||||
|
||||
Reference in New Issue
Block a user