🐛 Fix bot libs mount behavior and prop types
This commit is contained in:
13
.github/workflows/publish-typebot-js.yml
vendored
13
.github/workflows/publish-typebot-js.yml
vendored
@@ -8,15 +8,16 @@ on:
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./packages/js
|
||||
env:
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: pnpm/action-setup@v2.2.2
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- run: pnpm build
|
||||
- run: pnpm config set //registry.npmjs.org/:_authToken ${NPM_TOKEN}
|
||||
- run: pnpm publish --no-git-checks --access public
|
||||
- run: pnpm turbo build --filter=@typebot.io/js...
|
||||
- name: Set NPM_TOKEN in config
|
||||
run: pnpm config set //registry.npmjs.org/:_authToken ${NPM_TOKEN}
|
||||
working-directory: ./packages/js
|
||||
- name: Publish
|
||||
run: pnpm publish --no-git-checks --access public
|
||||
working-directory: ./packages/js
|
||||
|
||||
13
.github/workflows/publish-typebot-react.yml
vendored
13
.github/workflows/publish-typebot-react.yml
vendored
@@ -8,15 +8,16 @@ on:
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./packages/react
|
||||
env:
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: pnpm/action-setup@v2.2.2
|
||||
- run: pnpm i --frozen-lockfile
|
||||
- run: pnpm build
|
||||
- run: pnpm config set //registry.npmjs.org/:_authToken ${NPM_TOKEN}
|
||||
- run: pnpm publish --no-git-checks --access public
|
||||
- run: pnpm turbo build --filter=@typebot.io/react...
|
||||
- name: Set NPM_TOKEN in config
|
||||
run: pnpm config set //registry.npmjs.org/:_authToken ${NPM_TOKEN}
|
||||
working-directory: ./packages/react
|
||||
- name: Publish
|
||||
run: pnpm publish --no-git-checks --access public
|
||||
working-directory: ./packages/react
|
||||
|
||||
@@ -52,11 +52,10 @@ export const continueBotFlow =
|
||||
|
||||
const formattedReply = formatReply(reply, block.type)
|
||||
|
||||
if (
|
||||
!formattedReply ||
|
||||
!isReplyValid(formattedReply, block) ||
|
||||
(!formatReply && !canSkip(block.type))
|
||||
)
|
||||
if (!formattedReply && !canSkip(block.type)) {
|
||||
return parseRetryMessage(block)
|
||||
}
|
||||
if (formattedReply && !isReplyValid(formattedReply, block))
|
||||
return parseRetryMessage(block)
|
||||
|
||||
const newVariables = await processAndSaveAnswer(
|
||||
@@ -98,7 +97,8 @@ const processAndSaveAnswer =
|
||||
state: Pick<SessionState, 'result' | 'typebot' | 'isPreview'>,
|
||||
block: InputBlock
|
||||
) =>
|
||||
async (reply: string): Promise<Variable[]> => {
|
||||
async (reply: string | null): Promise<Variable[]> => {
|
||||
if (!reply) return state.typebot.variables
|
||||
if (!state.isPreview && state.result) {
|
||||
await saveAnswer(state.result.id, block)(reply)
|
||||
if (!state.result.hasStarted) await setResultAsStarted(state.result.id)
|
||||
@@ -201,7 +201,7 @@ const computeStorageUsed = async (reply: string) => {
|
||||
|
||||
const getOutgoingEdgeId =
|
||||
({ typebot: { variables } }: Pick<SessionState, 'typebot'>) =>
|
||||
(block: InputBlock, reply?: string) => {
|
||||
(block: InputBlock, reply: string | null) => {
|
||||
if (
|
||||
block.type === InputBlockType.CHOICE &&
|
||||
!block.options.isMultipleChoice &&
|
||||
|
||||
6
packages/js/.npmignore
Normal file
6
packages/js/.npmignore
Normal file
@@ -0,0 +1,6 @@
|
||||
src
|
||||
.eslintignore
|
||||
.eslintrc.cjs
|
||||
rollup.config.js
|
||||
tailwind.config.cjs
|
||||
tsconfig.json
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@typebot.io/js",
|
||||
"version": "0.0.5",
|
||||
"version": "0.0.6",
|
||||
"description": "Javascript library to display typebots on your website",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
|
||||
@@ -152,7 +152,7 @@ const BotContent = (props: BotContentProps) => {
|
||||
const font = document.createElement('link')
|
||||
font.href = `https://fonts.googleapis.com/css2?family=${
|
||||
props.initialChatReply.typebot?.theme?.general?.font ?? 'Open Sans'
|
||||
}:wght@300;400;600&display=swap')`
|
||||
}:ital,wght@0,300;0,400;0,600;1,300;1,400;1,600&display=swap');')`
|
||||
font.rel = 'stylesheet'
|
||||
document.head.appendChild(font)
|
||||
}
|
||||
|
||||
@@ -48,6 +48,11 @@ export const InputChatBlock = (props: Props) => {
|
||||
props.onSubmit(value ?? label)
|
||||
}
|
||||
|
||||
const handleSkip = (label: string) => {
|
||||
setAnswer(label)
|
||||
props.onSkip()
|
||||
}
|
||||
|
||||
return (
|
||||
<Switch>
|
||||
<Match when={answer()} keyed>
|
||||
@@ -75,7 +80,7 @@ export const InputChatBlock = (props: Props) => {
|
||||
inputIndex={props.inputIndex}
|
||||
isInputPrefillEnabled={props.isInputPrefillEnabled}
|
||||
onSubmit={handleSubmit}
|
||||
onSkip={() => props.onSkip()}
|
||||
onSkip={handleSkip}
|
||||
hasGuestAvatar={props.guestAvatar?.isEnabled ?? false}
|
||||
/>
|
||||
</div>
|
||||
@@ -91,7 +96,7 @@ const Input = (props: {
|
||||
hasGuestAvatar: boolean
|
||||
isInputPrefillEnabled: boolean
|
||||
onSubmit: (answer: InputSubmitContent) => void
|
||||
onSkip: () => void
|
||||
onSkip: (label: string) => void
|
||||
}) => {
|
||||
const onSubmit = (answer: InputSubmitContent) => props.onSubmit(answer)
|
||||
|
||||
@@ -165,7 +170,6 @@ const Input = (props: {
|
||||
context={props.context}
|
||||
block={props.block as FileInputBlock}
|
||||
onSubmit={onSubmit}
|
||||
// eslint-disable-next-line solid/reactivity
|
||||
onSkip={props.onSkip}
|
||||
/>
|
||||
</Match>
|
||||
|
||||
@@ -14,7 +14,7 @@ export const Avatar = (props: { initialAvatarSrc?: string }) => {
|
||||
>
|
||||
<figure
|
||||
class={
|
||||
'flex justify-center items-center rounded-full text-white relative animate-fade-in ' +
|
||||
'flex justify-center items-center rounded-full text-white relative animate-fade-in flex-shrink-0 ' +
|
||||
(isMobile() ? 'w-6 h-6 text-sm' : 'w-10 h-10 text-xl')
|
||||
}
|
||||
>
|
||||
|
||||
@@ -9,7 +9,7 @@ type Props = {
|
||||
context: BotContext
|
||||
block: FileInputBlock
|
||||
onSubmit: (url: InputSubmitContent) => void
|
||||
onSkip: () => void
|
||||
onSkip: (label: string) => void
|
||||
}
|
||||
|
||||
export const FileUploadForm = (props: Props) => {
|
||||
@@ -178,7 +178,12 @@ export const FileUploadForm = (props: Props) => {
|
||||
class={
|
||||
'py-2 px-4 justify-center font-semibold rounded-md text-white focus:outline-none flex items-center disabled:opacity-50 disabled:cursor-not-allowed disabled:brightness-100 transition-all filter hover:brightness-90 active:brightness-75 typebot-button '
|
||||
}
|
||||
on:click={() => props.onSkip()}
|
||||
on:click={() =>
|
||||
props.onSkip(
|
||||
props.block.options.labels.skip ??
|
||||
defaultFileInputOptions.labels.skip
|
||||
)
|
||||
}
|
||||
>
|
||||
{props.block.options.labels.skip ??
|
||||
defaultFileInputOptions.labels.skip}
|
||||
|
||||
@@ -124,6 +124,7 @@ export const Bubble = (props: BubbleProps) => {
|
||||
'transform-origin': 'bottom right',
|
||||
transform: isBotOpened() ? 'scale3d(1, 1, 1)' : 'scale3d(0, 0, 1)',
|
||||
'box-shadow': 'rgb(0 0 0 / 16%) 0px 5px 40px',
|
||||
'background-color': bubbleProps.theme?.chatWindow?.backgroundColor,
|
||||
}}
|
||||
class={
|
||||
'absolute bottom-20 sm:right-4 rounded-lg w-full sm:w-[400px] max-h-[704px] ' +
|
||||
|
||||
@@ -4,10 +4,15 @@ export type BubbleParams = {
|
||||
}
|
||||
|
||||
export type BubbleTheme = {
|
||||
chatWindow?: ChatWindowTheme
|
||||
button?: ButtonTheme
|
||||
previewMessage?: PreviewMessageTheme
|
||||
}
|
||||
|
||||
export type ChatWindowTheme = {
|
||||
backgroundColor?: string
|
||||
}
|
||||
|
||||
export type ButtonTheme = {
|
||||
backgroundColor?: string
|
||||
iconColor?: string
|
||||
|
||||
@@ -23,7 +23,7 @@ export const fileInputStepSchema = blockBaseSchema.and(
|
||||
})
|
||||
)
|
||||
|
||||
export const defaultFileInputOptions: FileInputOptions = {
|
||||
export const defaultFileInputOptions = {
|
||||
isRequired: true,
|
||||
isMultipleAllowed: false,
|
||||
labels: {
|
||||
@@ -35,7 +35,7 @@ export const defaultFileInputOptions: FileInputOptions = {
|
||||
clear: 'Clear',
|
||||
skip: 'Skip',
|
||||
},
|
||||
}
|
||||
} satisfies FileInputOptions
|
||||
|
||||
export type FileInputBlock = z.infer<typeof fileInputStepSchema>
|
||||
export type FileInputOptions = z.infer<typeof fileInputOptionsSchema>
|
||||
|
||||
6
packages/react/.npmignore
Normal file
6
packages/react/.npmignore
Normal file
@@ -0,0 +1,6 @@
|
||||
src
|
||||
.env.local.example
|
||||
.eslintignore
|
||||
.eslintrc.cjs
|
||||
rollup.config.js
|
||||
tsconfig.json
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@typebot.io/react",
|
||||
"version": "0.0.5",
|
||||
"version": "0.0.6",
|
||||
"description": "React library to display typebots on your website",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
@@ -41,7 +41,7 @@
|
||||
"utils": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "18.0.0",
|
||||
"react": "18.x",
|
||||
"@typebot.io/js": "workspace:*"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,9 +22,17 @@ export const Bubble = (props: Props) => {
|
||||
useEffect(() => {
|
||||
;(async () => {
|
||||
await import('@typebot.io/js/dist/web')
|
||||
initBubble()
|
||||
})()
|
||||
return () => {
|
||||
ref.current?.remove()
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
updateProps(ref.current, props)
|
||||
}, [props])
|
||||
|
||||
const updateProps = (element: BubbleElement | null, props: Props) => {
|
||||
if (!element) return
|
||||
Object.assign(element, props)
|
||||
@@ -34,20 +42,10 @@ export const Bubble = (props: Props) => {
|
||||
const bubbleElement = document.createElement(
|
||||
'typebot-bubble'
|
||||
) as BubbleElement
|
||||
if (ref.current) return
|
||||
ref.current = bubbleElement
|
||||
document.body.append(bubbleElement)
|
||||
document.body.append(ref.current)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
;(async () => {
|
||||
if (!ref.current) await initBubble()
|
||||
updateProps(ref.current, props)
|
||||
})()
|
||||
|
||||
return () => {
|
||||
ref.current?.remove()
|
||||
}
|
||||
}, [props])
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -22,30 +22,28 @@ export const Popup = (props: Props) => {
|
||||
useEffect(() => {
|
||||
;(async () => {
|
||||
await import('@typebot.io/js/dist/web')
|
||||
initPopup()
|
||||
})()
|
||||
return () => {
|
||||
ref.current?.remove()
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
updateProps(ref.current, props)
|
||||
}, [props])
|
||||
|
||||
const updateProps = (element: PopupElement | null, props: Props) => {
|
||||
if (!element) return
|
||||
Object.assign(element, props)
|
||||
}
|
||||
|
||||
const initBubble = async () => {
|
||||
const initPopup = async () => {
|
||||
const popupElement = document.createElement('typebot-popup') as PopupElement
|
||||
if (ref.current) return
|
||||
ref.current = popupElement
|
||||
document.body.append(popupElement)
|
||||
document.body.append(ref.current)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
;(async () => {
|
||||
if (!ref.current) await initBubble()
|
||||
updateProps(ref.current, props)
|
||||
})()
|
||||
|
||||
return () => {
|
||||
ref.current?.remove()
|
||||
}
|
||||
}, [props])
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user