🚸 Make entire screen scrollable when chat container is disabled

Closes #2089
This commit is contained in:
Baptiste Arnaud 2025-03-24 18:30:59 +01:00
parent 0c531aff66
commit 80498808ff
No known key found for this signature in database
26 changed files with 129 additions and 114 deletions

BIN
bun.lockb

Binary file not shown.

View File

@ -1,6 +1,6 @@
{
"name": "@typebot.io/js",
"version": "0.3.70",
"version": "0.3.71",
"description": "Javascript library to display typebots on your website",
"license": "FSL-1.1-ALv2",
"type": "module",
@ -19,7 +19,6 @@
"@ark-ui/solid": "5.0.0",
"@fix-webm-duration/fix": "1.0.1",
"@stripe/stripe-js": "1.54.1",
"clsx": "2.1.1",
"dompurify": "3.0.6",
"ky": "1.2.4",
"marked": "9.0.3",

View File

@ -130,13 +130,11 @@ pre {
.typebot-chat-view {
@apply pt-5 px-3;
max-width: var(--typebot-chat-container-max-width);
background-color: rgba(
var(--typebot-chat-container-bg-rgb),
var(--typebot-chat-container-opacity)
);
color: rgb(var(--typebot-chat-container-color));
min-height: 100%;
backdrop-filter: blur(var(--typebot-chat-container-blur));
border-width: var(--typebot-chat-container-border-width);
border-color: rgba(

View File

@ -1,4 +1,4 @@
import clsx from "clsx";
import { cx } from "@typebot.io/ui/lib/cva";
import { type JSX, Show, children, splitProps } from "solid-js";
import { Spinner } from "./Spinner";
@ -25,7 +25,7 @@ export const Button = (props: ButtonProps) => {
<button
{...buttonProps}
disabled={local.isDisabled || local.isLoading}
class={clsx(
class={cx(
"py-2 px-4 font-semibold focus:outline-none filter hover:brightness-90 active:brightness-75 disabled:opacity-50 disabled:cursor-not-allowed disabled:brightness-100 flex justify-center flex-shrink-0 transition-[filter] duration-200",
local.variant === "secondary"
? "secondary-button bg-host-bubble-bg text-host-bubble-text rounded-host-bubble border-host-bubble border-host-bubble-border"

View File

@ -37,7 +37,11 @@ import { isNotDefined } from "@typebot.io/lib/utils";
import type { LogInSession } from "@typebot.io/logs/schemas";
import { latestTypebotVersion } from "@typebot.io/schemas/versions";
import { defaultSystemMessages } from "@typebot.io/settings/constants";
import { BackgroundType } from "@typebot.io/theme/constants";
import {
BackgroundType,
defaultContainerBackgroundColor,
} from "@typebot.io/theme/constants";
import { cx } from "@typebot.io/ui/lib/cva";
import {
For,
Show,
@ -540,61 +544,69 @@ export const ConversationContainer = (props: Props) => {
return (
<div
ref={chatContainer}
class="flex flex-col overflow-y-auto w-full relative scrollable-container typebot-chat-view scroll-smooth gap-2"
class={cx(
"flex flex-col overflow-y-auto relative scrollable-container typebot-chat-view scroll-smooth gap-2 w-full min-h-full items-center",
(props.initialChatReply.typebot.theme.chat?.container
?.backgroundColor ?? defaultContainerBackgroundColor) ===
"transparent" && "max-w-chat-container",
)}
>
<For each={chatChunks().slice(0, totalChunksDisplayed() + 1)}>
{(chatChunk, index) => (
<ChatChunk
index={index()}
messages={chatChunk.messages}
input={chatChunk.input}
<div class="max-w-chat-container w-full">
<For each={chatChunks().slice(0, totalChunksDisplayed() + 1)}>
{(chatChunk, index) => (
<ChatChunk
index={index()}
messages={chatChunk.messages}
input={chatChunk.input}
theme={props.initialChatReply.typebot.theme}
avatarsHistory={avatarsHistory()}
settings={props.initialChatReply.typebot.settings}
streamingMessageId={chatChunk.streamingMessageId}
context={props.context}
hideAvatar={
(!chatChunk.input ||
hiddenInput()[`${chatChunk.input.id}-${index()}`]) &&
((
chatChunks().slice(0, totalChunksDisplayed() + 1)[index() + 1]
?.messages ?? []
).length > 0 ||
chatChunks().slice(0, totalChunksDisplayed() + 1)[index() + 1]
?.streamingMessageId !== undefined ||
(chatChunk.messages.length > 0 && isSending()))
}
hasError={
hasError() &&
index() ===
chatChunks().slice(0, totalChunksDisplayed() + 1).length - 1
}
isTransitionDisabled={
index() !==
chatChunks().slice(0, totalChunksDisplayed() + 1).length - 1
}
isOngoingLastChunk={
!isEnded() &&
index() ===
chatChunks().slice(0, totalChunksDisplayed() + 1).length - 1
}
onNewBubbleDisplayed={handleNewBubbleDisplayed}
onAllBubblesDisplayed={handleAllBubblesDisplayed}
onSubmit={sendMessage}
onScrollToBottom={autoScrollToBottom}
onSkip={handleSkip}
/>
)}
</For>
<Show when={isSending()}>
<LoadingChunk
theme={props.initialChatReply.typebot.theme}
avatarsHistory={avatarsHistory()}
settings={props.initialChatReply.typebot.settings}
streamingMessageId={chatChunk.streamingMessageId}
context={props.context}
hideAvatar={
(!chatChunk.input ||
hiddenInput()[`${chatChunk.input.id}-${index()}`]) &&
((
chatChunks().slice(0, totalChunksDisplayed() + 1)[index() + 1]
?.messages ?? []
).length > 0 ||
chatChunks().slice(0, totalChunksDisplayed() + 1)[index() + 1]
?.streamingMessageId !== undefined ||
(chatChunk.messages.length > 0 && isSending()))
avatarSrc={
avatarsHistory().findLast((avatar) => avatar.role === "host")
?.avatarUrl
}
hasError={
hasError() &&
index() ===
chatChunks().slice(0, totalChunksDisplayed() + 1).length - 1
}
isTransitionDisabled={
index() !==
chatChunks().slice(0, totalChunksDisplayed() + 1).length - 1
}
isOngoingLastChunk={
!isEnded() &&
index() ===
chatChunks().slice(0, totalChunksDisplayed() + 1).length - 1
}
onNewBubbleDisplayed={handleNewBubbleDisplayed}
onAllBubblesDisplayed={handleAllBubblesDisplayed}
onSubmit={sendMessage}
onScrollToBottom={autoScrollToBottom}
onSkip={handleSkip}
/>
)}
</For>
<Show when={isSending()}>
<LoadingChunk
theme={props.initialChatReply.typebot.theme}
avatarSrc={
avatarsHistory().findLast((avatar) => avatar.role === "host")
?.avatarUrl
}
/>
</Show>
</Show>
</div>
<BottomSpacer />
</div>
);

View File

@ -1,6 +1,6 @@
import { isMobile } from "@/utils/isMobileSignal";
import { isEmpty } from "@typebot.io/lib/utils";
import clsx from "clsx";
import { cx } from "@typebot.io/ui/lib/cva";
import { Match, Switch, splitProps } from "solid-js";
import { Button, type ButtonProps } from "./Button";
import { SendIcon } from "./icons/SendIcon";
@ -26,7 +26,7 @@ export const SendButton = (props: SendButtonProps) => {
<Button
{...buttonProps}
type="submit"
class={clsx(buttonProps.class, "flex items-center")}
class={cx(buttonProps.class, "flex items-center")}
aria-label={showIcon ? "Send" : undefined}
>
<Switch>

View File

@ -1,6 +1,6 @@
import { isMobile } from "@/utils/isMobileSignal";
import { Menu } from "@ark-ui/solid";
import clsx from "clsx";
import { cx } from "@typebot.io/ui/lib/cva";
import { Match, Switch } from "solid-js";
import { FileIcon } from "./icons/FileIcon";
import { PaperClipIcon } from "./icons/PaperClipIcon";
@ -40,7 +40,7 @@ export const TextInputAddFileButton = (props: Props) => {
<label
aria-label="Add attachments"
for="document-upload"
class={clsx(
class={cx(
"filter data-[state=open]:backdrop-brightness-90 hover:backdrop-brightness-95 transition rounded-md p-2 focus:outline-none",
props.class,
)}
@ -51,7 +51,7 @@ export const TextInputAddFileButton = (props: Props) => {
<Match when={true}>
<Menu.Root>
<Menu.Trigger
class={clsx(
class={cx(
"filter data-[state=open]:backdrop-brightness-90 hover:backdrop-brightness-95 transition rounded-md p-2 focus:outline-none",
props.class,
)}

View File

@ -12,7 +12,7 @@ import {
} from "@typebot.io/theme/constants";
import { isChatContainerLight } from "@typebot.io/theme/helpers/isChatContainerLight";
import type { Theme } from "@typebot.io/theme/schemas";
import clsx from "clsx";
import { cx } from "@typebot.io/ui/lib/cva";
import { For, Match, Show, Switch, createSignal } from "solid-js";
import { Modal } from "../Modal";
import { Avatar } from "../avatars/Avatar";
@ -73,7 +73,7 @@ const TextGuestBubble = (props: { answer: TextInputSubmitContent }) => {
<div class="flex flex-col gap-1 items-end">
<Show when={(props.answer.attachments ?? []).length > 0}>
<div
class={clsx(
class={cx(
"flex gap-1 overflow-auto max-w-[350px]",
isMobile() ? "flex-wrap justify-end" : "items-center",
)}
@ -87,7 +87,7 @@ const TextGuestBubble = (props: { answer: TextInputSubmitContent }) => {
<img
src={attachment.blobUrl ?? attachment.url}
alt={`Attached image ${idx() + 1}`}
class={clsx(
class={cx(
"typebot-guest-bubble-image-attachment cursor-pointer",
props.answer.attachments!.filter((attachment) =>
attachment.type.startsWith("image"),
@ -101,7 +101,7 @@ const TextGuestBubble = (props: { answer: TextInputSubmitContent }) => {
</For>
</div>
<div
class={clsx(
class={cx(
"flex gap-1 overflow-auto max-w-[350px]",
isMobile() ? "flex-wrap justify-end" : "items-center",
)}

View File

@ -2,7 +2,7 @@ import { TypingBubble } from "@/components/TypingBubble";
import { isMobile } from "@/utils/isMobileSignal";
import { defaultAudioBubbleContent } from "@typebot.io/blocks-bubbles/audio/constants";
import type { AudioBubbleBlock } from "@typebot.io/blocks-bubbles/audio/schema";
import clsx from "clsx";
import { cx } from "@typebot.io/ui/lib/cva";
import { createSignal, onCleanup, onMount } from "solid-js";
type Props = {
@ -38,7 +38,7 @@ export const AudioBubble = (props: Props) => {
return (
<div
class={clsx(
class={cx(
"flex flex-col",
props.onTransitionEnd ? "animate-fade-in" : undefined,
)}

View File

@ -4,7 +4,7 @@ import type { InputSubmitContent } from "@/types";
import { botContainerHeight } from "@/utils/botContainerHeightSignal";
import { isMobile } from "@/utils/isMobileSignal";
import type { CustomEmbedBubble as CustomEmbedBubbleProps } from "@typebot.io/bot-engine/schemas/api";
import clsx from "clsx";
import { cx } from "@typebot.io/ui/lib/cva";
import { createSignal, onCleanup, onMount } from "solid-js";
type Props = {
@ -55,7 +55,7 @@ export const CustomEmbedBubble = (props: Props) => {
return (
<div
class={clsx(
class={cx(
"flex flex-col w-full",
props.onTransitionEnd ? "animate-fade-in" : undefined,
)}
@ -73,7 +73,7 @@ export const CustomEmbedBubble = (props: Props) => {
{isTyping() && <TypingBubble />}
</div>
<div
class={clsx(
class={cx(
"p-2 z-20 text-fade-in w-full",
isTyping() ? "opacity-0" : "opacity-100",
)}

View File

@ -4,7 +4,7 @@ import { isMobile } from "@/utils/isMobileSignal";
import { defaultEmbedBubbleContent } from "@typebot.io/blocks-bubbles/embed/constants";
import type { EmbedBubbleBlock } from "@typebot.io/blocks-bubbles/embed/schema";
import { isNotEmpty } from "@typebot.io/lib/utils";
import clsx from "clsx";
import { cx } from "@typebot.io/ui/lib/cva";
import { createSignal, onCleanup, onMount } from "solid-js";
type Props = {
@ -62,7 +62,7 @@ export const EmbedBubble = (props: Props) => {
return (
<div
class={clsx(
class={cx(
"flex flex-col w-full",
props.onTransitionEnd ? "animate-fade-in" : undefined,
)}
@ -80,7 +80,7 @@ export const EmbedBubble = (props: Props) => {
{isTyping() && <TypingBubble />}
</div>
<div
class={clsx(
class={cx(
"p-4 z-20 text-fade-in w-full",
isTyping() ? "opacity-0" : "opacity-100 p-4",
)}

View File

@ -3,7 +3,7 @@ import { TypingBubble } from "@/components/TypingBubble";
import { isMobile } from "@/utils/isMobileSignal";
import { defaultImageBubbleContent } from "@typebot.io/blocks-bubbles/image/constants";
import type { ImageBubbleBlock } from "@typebot.io/blocks-bubbles/image/schema";
import clsx from "clsx";
import { cx } from "@typebot.io/ui/lib/cva";
import { createSignal, onCleanup, onMount } from "solid-js";
type Props = {
@ -61,7 +61,7 @@ export const ImageBubble = (props: Props) => {
alt={
props.content?.clickLink?.alt ?? defaultImageBubbleContent.clickLink.alt
}
class={clsx(
class={cx(
isTyping() ? "opacity-0" : "opacity-100",
props.onTransitionEnd ? "text-fade-in" : undefined,
props.content?.url?.endsWith(".svg") ? "w-full" : undefined,
@ -82,7 +82,7 @@ export const ImageBubble = (props: Props) => {
return (
<div
class={clsx(
class={cx(
"flex flex-col",
props.onTransitionEnd ? "animate-fade-in" : undefined,
)}
@ -103,14 +103,14 @@ export const ImageBubble = (props: Props) => {
<a
href={props.content.clickLink.url}
target="_blank"
class={clsx("z-10", isTyping() ? "h-8" : "p-4")}
class={cx("z-10", isTyping() ? "h-8" : "p-4")}
rel="noreferrer"
>
{Image}
</a>
) : (
<figure
class={clsx(
class={cx(
"z-10 cursor-pointer",
!isTyping() && "p-4",
isTyping() ? (isMobile() ? "h-8" : "h-9") : "",

View File

@ -3,7 +3,7 @@ import { isMobile } from "@/utils/isMobileSignal";
import type { TextBubbleBlock } from "@typebot.io/blocks-bubbles/text/schema";
import { computeTypingDuration } from "@typebot.io/settings/computeTypingDuration";
import type { Settings } from "@typebot.io/settings/schemas";
import clsx from "clsx";
import { cx } from "@typebot.io/ui/lib/cva";
import { For, createSignal, onCleanup, onMount } from "solid-js";
import { computePlainText } from "../helpers/convertRichTextToPlainText";
import { PlateElement } from "./plate/PlateBlock";
@ -54,7 +54,7 @@ export const TextBubble = (props: Props) => {
return (
<div
class={clsx(
class={cx(
"flex flex-col",
props.onTransitionEnd ? "animate-fade-in" : undefined,
)}
@ -73,7 +73,7 @@ export const TextBubble = (props: Props) => {
{isTyping() && <TypingBubble />}
</div>
<div
class={clsx(
class={cx(
"overflow-hidden text-fade-in mx-4 my-2 whitespace-pre-wrap slate-html-container relative text-ellipsis",
isTyping() ? "opacity-0" : "opacity-100",
)}

View File

@ -11,7 +11,7 @@ import type {
EmbeddableVideoBubbleContentType,
VideoBubbleBlock,
} from "@typebot.io/blocks-bubbles/video/schema";
import { clsx } from "clsx";
import { cx } from "@typebot.io/ui/lib/cva";
import { Match, Switch, createSignal, onCleanup, onMount } from "solid-js";
type Props = {
@ -51,7 +51,7 @@ export const VideoBubble = (props: Props) => {
return (
<div
class={clsx(
class={cx(
"flex flex-col w-full",
props.onTransitionEnd ? "animate-fade-in" : undefined,
)}
@ -111,7 +111,7 @@ export const VideoBubble = (props: Props) => {
}
>
<div
class={clsx(
class={cx(
"p-4 z-10 text-fade-in w-full",
isTyping() ? "opacity-0" : "opacity-100 p-4",
)}

View File

@ -2,7 +2,7 @@ import { SendButton } from "@/components/SendButton";
import type { InputSubmitContent } from "@/types";
import { defaultDateInputOptions } from "@typebot.io/blocks-inputs/date/constants";
import type { DateInputBlock } from "@typebot.io/blocks-inputs/date/schema";
import clsx from "clsx";
import { cx } from "@typebot.io/ui/lib/cva";
import { createSignal } from "solid-js";
type Props = {
@ -29,7 +29,7 @@ export const DateForm = (props: Props) => {
return (
<div class="typebot-input-form flex gap-2 items-end">
<form
class={clsx(
class={cx(
"flex typebot-input",
props.options?.isRange ? "items-end" : "items-center",
)}

View File

@ -1,5 +1,5 @@
import { FileIcon } from "@/components/icons/FileIcon";
import clsx from "clsx";
import { cx } from "@typebot.io/ui/lib/cva";
type Props = {
file: { name: string };
@ -15,7 +15,7 @@ export const FilePreview = (props: Props) => {
}
>
<div
class={clsx(
class={cx(
"rounded-md text-white p-2 flex items-center",
fileColor === "pink" && "bg-pink-400",
fileColor === "blue" && "bg-blue-400",

View File

@ -14,7 +14,7 @@ import { defaultTextInputOptions } from "@typebot.io/blocks-inputs/text/constant
import type { TextInputBlock } from "@typebot.io/blocks-inputs/text/schema";
import { getRuntimeVariable } from "@typebot.io/env/getRuntimeVariable";
import { isDefined } from "@typebot.io/lib/utils";
import clsx from "clsx";
import { cx } from "@typebot.io/ui/lib/cva";
import {
For,
Match,
@ -252,7 +252,7 @@ export const TextInput = (props: Props) => {
return (
<div
class={clsx(
class={cx(
"typebot-input-form flex w-full gap-2 items-end",
props.block.options?.isLong && recordingStatus() !== "started"
? "max-w-full"
@ -264,7 +264,7 @@ export const TextInput = (props: Props) => {
onDragLeave={handleDragLeave}
>
<div
class={clsx(
class={cx(
"relative typebot-input flex-col w-full",
isDraggingOver() && "filter brightness-95",
)}
@ -302,7 +302,7 @@ export const TextInput = (props: Props) => {
</div>
</Show>
<div
class={clsx(
class={cx(
"flex justify-between px-2",
props.block.options?.isLong ? "items-end" : "items-center",
)}
@ -338,7 +338,7 @@ export const TextInput = (props: Props) => {
>
<TextInputAddFileButton
onNewFiles={onNewFiles}
class={clsx(props.block.options?.isLong ? "ml-2" : undefined)}
class={cx(props.block.options?.isLong ? "ml-2" : undefined)}
/>
</Show>
</div>

View File

@ -4,7 +4,7 @@ import { hexToRgb } from "@typebot.io/lib/hexToRgb";
import { isTypebotVersionAtLeastV6 } from "@typebot.io/schemas/helpers/isTypebotVersionAtLeastV6";
import { defaultButtonsBackgroundColor } from "@typebot.io/theme/constants";
import type { Theme } from "@typebot.io/theme/schemas";
import clsx from "clsx";
import { cx } from "@typebot.io/ui/lib/cva";
import { createEffect, createSignal, onCleanup } from "solid-js";
import { volumeProcessorCode } from "./VolumeProcessor";
@ -159,7 +159,7 @@ export const VoiceRecorder = (props: Props) => {
return (
<div
class={clsx(
class={cx(
"w-full gap-2 items-center transition-opacity px-2 typebot-recorder",
props.recordingStatus === "started"
? "opacity-1 flex"

View File

@ -9,8 +9,8 @@ import {
} from "@/utils/storage";
import { EnvironmentProvider } from "@ark-ui/solid";
import { isDefined, isNotDefined } from "@typebot.io/lib/utils";
import { cx } from "@typebot.io/ui/lib/cva";
import { zendeskWebWidgetOpenedMessage } from "@typebot.io/zendesk-block/constants";
import clsx from "clsx";
import {
Show,
createEffect,
@ -188,7 +188,7 @@ export const Bubble = (props: BubbleProps) => {
<style>{styles}</style>
<div ref={progressBarContainerRef} />
<div
class={clsx(
class={cx(
bubbleProps.theme?.position !== "static"
? bubbleProps.theme?.placement === "left"
? "z-[424242] fixed bottom-5 left-5"
@ -233,7 +233,7 @@ export const Bubble = (props: BubbleProps) => {
"background-color":
bubbleProps.theme?.chatWindow?.backgroundColor,
}}
class={clsx(
class={cx(
"absolute rounded-lg w-screen bottom-[calc(100%+12px)]",
isBotOpened() ? "opacity-1" : "opacity-0 pointer-events-none",
bubbleProps.theme?.placement === "left"

View File

@ -1,7 +1,7 @@
import { isLight } from "@typebot.io/lib/hexToRgb";
import { isNotDefined, isSvgSrc } from "@typebot.io/lib/utils";
import { colors } from "@typebot.io/ui/colors";
import { clsx } from "clsx";
import { cx } from "@typebot.io/ui/lib/cva";
import { Match, Switch } from "solid-js";
import type { BubbleTheme, ButtonTheme } from "../types";
@ -21,7 +21,7 @@ export const BubbleButton = (props: Props) => (
<button
part="button"
onClick={() => props.toggleBot()}
class={clsx(
class={cx(
"relative shadow-md rounded-2xl hover:scale-110 active:scale-95 transition-transform duration-200 flex justify-center items-center animate-fade-in",
)}
style={{
@ -47,7 +47,7 @@ const OpenIcon = (props: Props) => (
<svg
part="button-icon"
viewBox="0 0 16 16"
class={clsx(
class={cx(
"fill-transparent absolute duration-200 transition size-6",
props.isBotOpened ? "scale-0 opacity-0" : "scale-100 opacity-100",
)}
@ -62,7 +62,7 @@ const OpenIcon = (props: Props) => (
<img
part="button-icon"
src={props.customIconSrc}
class={clsx(
class={cx(
"duration-200 transition",
props.isBotOpened ? "scale-0 opacity-0" : "scale-100 opacity-100",
isSvgSrc(props.customIconSrc) ? "w-[60%]" : "w-full h-full",
@ -74,7 +74,7 @@ const OpenIcon = (props: Props) => (
<Match when={props.customIconSrc && !isImageSrc(props.customIconSrc)}>
<span
part="button-icon"
class={clsx(
class={cx(
"text-4xl duration-200 transition",
props.isBotOpened ? "scale-0 opacity-0" : "scale-100 opacity-100",
)}
@ -98,7 +98,7 @@ const CloseIcon = (props: Props) => (
style={{
fill: defaultLightIconColor,
}}
class={clsx(
class={cx(
"absolute duration-200 transition w-[60%]",
props.isBotOpened
? "scale-100 rotate-0 opacity-100"
@ -118,7 +118,7 @@ const CloseIcon = (props: Props) => (
<img
part="button-icon"
src={props.customCloseIconSrc}
class={clsx(
class={cx(
"absolute duration-200 transition",
props.isBotOpened
? "scale-100 rotate-0 opacity-100"
@ -134,7 +134,7 @@ const CloseIcon = (props: Props) => (
>
<span
part="button-icon"
class={clsx(
class={cx(
"absolute text-4xl duration-200 transition",
props.isBotOpened
? "scale-100 rotate-0 opacity-100"

View File

@ -1,4 +1,4 @@
import clsx from "clsx";
import { cx } from "@typebot.io/ui/lib/cva";
import { Show, createSignal } from "solid-js";
import type {
BubbleTheme,
@ -50,7 +50,7 @@ export const PreviewMessage = (props: PreviewMessageProps) => {
<div
part="preview-message"
onClick={() => props.onClick()}
class={clsx(
class={cx(
"absolute bottom-[calc(100%+12px)] w-64 rounded-md duration-200 flex items-center gap-4 shadow-md animate-fade-in cursor-pointer hover:shadow-lg p-4",
props.placement === "left" ? "left-0" : "right-0",
)}

View File

@ -0,0 +1,4 @@
import { createSignal } from "solid-js";
export const [scrollContainer, setScrollContainer] =
createSignal<HTMLDivElement>();

View File

@ -56,6 +56,9 @@ const config = {
"rgba(var(--typebot-input-border-rgb), var(--typebot-input-border-opacity));",
},
extend: {
maxWidth: {
"chat-container": "var(--typebot-chat-container-max-width)",
},
blur: {
button: "var(--typebot-button-blur)",
"host-bubble": "var(--typebot-host-bubble-blur)",

View File

@ -1,6 +1,6 @@
{
"name": "@typebot.io/nextjs",
"version": "0.3.70",
"version": "0.3.71",
"license": "FSL-1.1-ALv2",
"description": "Convenient library to display typebots on your Next.js website",
"type": "module",

View File

@ -1,6 +1,6 @@
{
"name": "@typebot.io/react",
"version": "0.3.70",
"version": "0.3.71",
"description": "Convenient library to display typebots on your React app",
"license": "FSL-1.1-ALv2",
"type": "module",

View File

@ -6966,7 +6966,6 @@
"@typebot.io/zendesk-block" "packages/forge/blocks/zendesk"
"@types/dompurify" "3.0.3"
autoprefixer "10.4.20"
clsx "2.1.1"
dompurify "3.0.6"
esbuild-plugin-solid "^0.6.0"
ky "1.2.4"
@ -12015,7 +12014,7 @@ clsx@2.0.0:
resolved "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz"
integrity sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==
clsx@2.1.1, clsx@^2.0.0, clsx@^2.1.1:
clsx@^2.0.0, clsx@^2.1.1:
version "2.1.1"
resolved "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz"
integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==