diff --git a/apps/builder/src/components/inputs/CodeEditor.tsx b/apps/builder/src/components/inputs/CodeEditor.tsx index 267d523de..4b989a5f6 100644 --- a/apps/builder/src/components/inputs/CodeEditor.tsx +++ b/apps/builder/src/components/inputs/CodeEditor.tsx @@ -163,6 +163,7 @@ export const CodeEditor = ({ basicSetup={{ highlightActiveLine: false, }} + placeholder={props.placeholder} /> {isVariableButtonDisplayed && ( { const updateFamily = (family: string) => onFontChange({ ...font, family }) - const updateUrl = (url: string) => onFontChange({ ...font, url }) + const updateCss = (css: string) => onFontChange({ ...font, css }) return ( - ) diff --git a/apps/docs/mint.json b/apps/docs/mint.json index bb14f1470..eb053a96e 100644 --- a/apps/docs/mint.json +++ b/apps/docs/mint.json @@ -1,10 +1,7 @@ { "$schema": "https://mintlify.com/schema.json", "name": "Typebot Docs", - "openapi": [ - "/openapi/builder.json", - "/openapi/viewer.json" - ], + "openapi": ["/openapi/builder.json", "/openapi/viewer.json"], "feedback": { "suggestEdit": true }, @@ -141,7 +138,7 @@ }, { "group": "Theme", - "pages": ["theme/overview"] + "pages": ["theme/overview", "theme/font"] }, { "group": "Settings", diff --git a/apps/docs/theme/font.mdx b/apps/docs/theme/font.mdx new file mode 100644 index 000000000..e878d87b1 --- /dev/null +++ b/apps/docs/theme/font.mdx @@ -0,0 +1,26 @@ +--- +title: Font +--- + +You can change the font of your typebot in the Theme tab under the Global section. + +There, you can choose between choosing a font from Google Fonts or defining your own custom font. + +## How to import my own font? + +You can import your own font by clicking on the "Custom" option. There you need to define the font family and the CSS that defines all the `@font-face` properties. + +For example, if I want to import my font called "Awesome Font", I would define the following family value: `"Awesome Font", "Helvetica Neue", sans-serif`. This should be a list of font names separated by commas. The first font name in the list is the font that will be used if it is available. If the name is not available, the browser will try to use the next font in the list. A font name that contains white-space should be quoted. + +Then I would define the content like so: + +```css +@font-face { + font-family: 'Awesome Font'; + src: url('https://example.com/awesome.woff') format('woff'), url('https://example.com/awesome.ttf') format('truetype'); +} +``` + + +The server providing the fonts (`https://example.com/awesome.woff`) needs to support HTTPS and Cross-Origin Resource Sharing (CORS). + diff --git a/packages/embeds/js/src/utils/injectFont.ts b/packages/embeds/js/src/utils/injectFont.ts index 9b45d2c0e..34a15c4e3 100644 --- a/packages/embeds/js/src/utils/injectFont.ts +++ b/packages/embeds/js/src/utils/injectFont.ts @@ -1,32 +1,44 @@ -import { isEmpty } from '@typebot.io/lib' +import { isNotEmpty } from '@typebot.io/lib' import { Font } from '@typebot.io/schemas' import { defaultTheme } from '@typebot.io/schemas/features/typebot/theme/constants' const googleFontCdnBaseUrl = 'https://fonts.bunny.net/css2' +const elementId = 'typebot-font' export const injectFont = (font: Font) => { - const existingFont = document.getElementById('bot-font') + const existingFont = document.getElementById(elementId) if (typeof font === 'string' || font.type === 'Google') { const fontFamily = (typeof font === 'string' ? font : font.family) ?? defaultTheme.general.font.family if (existingFont?.getAttribute('href')?.includes(fontFamily)) return + existingFont?.remove() const fontElement = document.createElement('link') fontElement.href = `${googleFontCdnBaseUrl}?family=${fontFamily}:ital,wght@0,300;0,400;0,600;1,300;1,400;1,600&display=swap` fontElement.rel = 'stylesheet' - fontElement.id = 'bot-font' + fontElement.id = elementId document.head.appendChild(fontElement) return } if (font.type === 'Custom') { - if (existingFont?.getAttribute('href') === font.url || isEmpty(font.url)) - return - const fontElement = document.createElement('link') - fontElement.href = font.url - fontElement.rel = 'stylesheet' - fontElement.id = 'bot-font' - document.head.appendChild(fontElement) + if (isNotEmpty(font.css)) { + if (existingFont?.innerHTML === font.css) return + existingFont?.remove() + const style = document.createElement('style') + style.innerHTML = font.css + style.id = elementId + document.head.appendChild(style) + } + if (isNotEmpty(font.url)) { + if (existingFont?.getAttribute('href') === font.url) return + existingFont?.remove() + const fontElement = document.createElement('link') + fontElement.href = font.url + fontElement.rel = 'stylesheet' + fontElement.id = elementId + document.head.appendChild(fontElement) + } } } diff --git a/packages/schemas/features/typebot/theme/schema.ts b/packages/schemas/features/typebot/theme/schema.ts index be42fe846..2d99176a6 100644 --- a/packages/schemas/features/typebot/theme/schema.ts +++ b/packages/schemas/features/typebot/theme/schema.ts @@ -47,7 +47,8 @@ export type GoogleFont = z.infer const customFontSchema = z.object({ type: z.literal(fontTypes[1]), family: z.string().optional(), - url: z.string().optional(), + css: z.string().optional(), + url: z.string().optional().describe('Deprecated, use `css` instead'), }) export type CustomFont = z.infer