mirror of
https://github.com/baptisteArno/typebot.io.git
synced 2026-06-16 21:10:26 +08:00
🚸 Make entire screen scrollable when chat container is disabled
Closes #2089
This commit is contained in:
parent
0c531aff66
commit
80498808ff
@ -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",
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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>
|
||||
);
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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,
|
||||
)}
|
||||
|
||||
@ -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",
|
||||
)}
|
||||
|
||||
@ -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,
|
||||
)}
|
||||
|
||||
@ -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",
|
||||
)}
|
||||
|
||||
@ -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",
|
||||
)}
|
||||
|
||||
@ -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") : "",
|
||||
|
||||
@ -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",
|
||||
)}
|
||||
|
||||
@ -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",
|
||||
)}
|
||||
|
||||
@ -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",
|
||||
)}
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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",
|
||||
)}
|
||||
|
||||
4
packages/embeds/js/src/utils/scrollContainer.ts
Normal file
4
packages/embeds/js/src/utils/scrollContainer.ts
Normal file
@ -0,0 +1,4 @@
|
||||
import { createSignal } from "solid-js";
|
||||
|
||||
export const [scrollContainer, setScrollContainer] =
|
||||
createSignal<HTMLDivElement>();
|
||||
@ -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)",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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==
|
||||
|
||||
Loading…
Reference in New Issue
Block a user