Compare commits

...

7 Commits

Author SHA1 Message Date
Dhruwang Jariwala
e3f3516fa7 fix: default preview colors (#7277) [Backport to release/4.7] (#7278)
Co-authored-by: Theodór Tómas <theodortomas@gmail.com>
2026-02-17 17:22:57 +05:30
Dhruwang Jariwala
91486f3dc9 fix: reduced default height of input (#7259) [Backport to release/4.7] (#7276) 2026-02-17 11:22:21 +05:30
Dhruwang Jariwala
8b9179bfcc fix: input placeholder color (#7265) [Backport to release/4.7] (#7275)
Co-authored-by: Theodór Tómas <theodortomas@gmail.com>
2026-02-17 11:21:50 +05:30
Dhruwang Jariwala
1b337aeac3 fix: suggest colors has better success copy (#7258) [Backport to release/4.7] (#7273)
Co-authored-by: Theodór Tómas <theodortomas@gmail.com>
2026-02-17 10:42:59 +05:30
Dhruwang Jariwala
cd64848cc5 fix: matrix table preview (#7257) [Backport to release/4.7] (#7272)
Co-authored-by: Theodór Tómas <theodortomas@gmail.com>
2026-02-17 10:42:46 +05:30
Dhruwang Jariwala
42411694a7 fix: fixes number being passed into string attribute (#7255) [Backport to release/4.7] (#7271)
Co-authored-by: Anshuman Pandey <54475686+pandeymangg@users.noreply.github.com>
2026-02-17 10:42:34 +05:30
Dhruwang Jariwala
721d972901 fix: input combobox height (#7256) [Backport to release/4.7] (#7270) 2026-02-17 10:27:16 +05:30
28 changed files with 260 additions and 115 deletions

View File

@@ -2036,12 +2036,12 @@ checksums:
environments/workspace/look/advanced_styling_field_headline_size_description: 13debc3855e4edae992c7a1ebff599c3 environments/workspace/look/advanced_styling_field_headline_size_description: 13debc3855e4edae992c7a1ebff599c3
environments/workspace/look/advanced_styling_field_headline_weight: 0c8b8262945c61f8e2978502362e0a42 environments/workspace/look/advanced_styling_field_headline_weight: 0c8b8262945c61f8e2978502362e0a42
environments/workspace/look/advanced_styling_field_headline_weight_description: 1a9c40bd76ff5098b1e48b1d3893171b environments/workspace/look/advanced_styling_field_headline_weight_description: 1a9c40bd76ff5098b1e48b1d3893171b
environments/workspace/look/advanced_styling_field_height: f4da6d7ecd26e3fa75cfea03abb60c00 environments/workspace/look/advanced_styling_field_height: 40ca2224bb2936ad1329091b35a9ffe2
environments/workspace/look/advanced_styling_field_indicator_bg: 00febda2901af0f1b0c17e44f9917c38 environments/workspace/look/advanced_styling_field_indicator_bg: 00febda2901af0f1b0c17e44f9917c38
environments/workspace/look/advanced_styling_field_indicator_bg_description: 7eb3b54a8b331354ec95c0dc1545c620 environments/workspace/look/advanced_styling_field_indicator_bg_description: 7eb3b54a8b331354ec95c0dc1545c620
environments/workspace/look/advanced_styling_field_input_border_radius_description: 0007f1bb572b35d9a3720daeb7a55617 environments/workspace/look/advanced_styling_field_input_border_radius_description: 0007f1bb572b35d9a3720daeb7a55617
environments/workspace/look/advanced_styling_field_input_font_size_description: 5311f95dcbd083623e35c98ea5374c3b environments/workspace/look/advanced_styling_field_input_font_size_description: 5311f95dcbd083623e35c98ea5374c3b
environments/workspace/look/advanced_styling_field_input_height_description: b704fc67e805223992c811d6f86a9c00 environments/workspace/look/advanced_styling_field_input_height_description: e19ec0dc432478def0fd1199ad765e38
environments/workspace/look/advanced_styling_field_input_padding_x_description: 10e14296468321c13fda77fd1ba58dfd environments/workspace/look/advanced_styling_field_input_padding_x_description: 10e14296468321c13fda77fd1ba58dfd
environments/workspace/look/advanced_styling_field_input_padding_y_description: 98b4aeff2940516d05ea61bdc1211d0d environments/workspace/look/advanced_styling_field_input_padding_y_description: 98b4aeff2940516d05ea61bdc1211d0d
environments/workspace/look/advanced_styling_field_input_placeholder_opacity_description: f55a6700884d24014404e58876121ddf environments/workspace/look/advanced_styling_field_input_placeholder_opacity_description: f55a6700884d24014404e58876121ddf
@@ -2104,6 +2104,7 @@ checksums:
environments/workspace/look/show_powered_by_formbricks: a0e96edadec8ef326423feccc9d06be7 environments/workspace/look/show_powered_by_formbricks: a0e96edadec8ef326423feccc9d06be7
environments/workspace/look/styling_updated_successfully: b8b74b50dde95abcd498633e9d0c891f environments/workspace/look/styling_updated_successfully: b8b74b50dde95abcd498633e9d0c891f
environments/workspace/look/suggest_colors: ddc4543b416ab774007b10a3434343cd environments/workspace/look/suggest_colors: ddc4543b416ab774007b10a3434343cd
environments/workspace/look/suggested_colors_applied_please_save: 226fa70af5efc8ffa0a3755909c8163e
environments/workspace/look/theme: 21fe00b7a518089576fb83c08631107a environments/workspace/look/theme: 21fe00b7a518089576fb83c08631107a
environments/workspace/look/theme_settings_description: 9fc45322818c3774ab4a44ea14d7836e environments/workspace/look/theme_settings_description: 9fc45322818c3774ab4a44ea14d7836e
environments/workspace/tags/add: 87c4a663507f2bcbbf79934af8164e13 environments/workspace/tags/add: 87c4a663507f2bcbbf79934af8164e13

View File

@@ -118,10 +118,10 @@ export const STYLE_DEFAULTS: TProjectStyling = {
// Inputs // Inputs
inputTextColor: { light: _colors["inputTextColor.light"] }, inputTextColor: { light: _colors["inputTextColor.light"] },
inputBorderRadius: 8, inputBorderRadius: 8,
inputHeight: 40, inputHeight: 20,
inputFontSize: 14, inputFontSize: 14,
inputPaddingX: 16, inputPaddingX: 8,
inputPaddingY: 16, inputPaddingY: 8,
inputPlaceholderOpacity: 0.5, inputPlaceholderOpacity: 0.5,
inputShadow: "0 1px 2px 0 rgb(0 0 0 / 0.05)", inputShadow: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
@@ -149,6 +149,42 @@ export const STYLE_DEFAULTS: TProjectStyling = {
progressIndicatorBgColor: { light: _colors["progressIndicatorBgColor.light"] }, progressIndicatorBgColor: { light: _colors["progressIndicatorBgColor.light"] },
}; };
/**
* Fills in new v4.7 color fields from legacy v4.6 fields when they are missing.
*
* v4.6 stored: brandColor, questionColor, inputColor, inputBorderColor.
* v4.7 adds: elementHeadlineColor, buttonBgColor, optionBgColor, etc.
*
* When loading v4.6 data the new fields are absent. Without this helper the
* form would fall back to STYLE_DEFAULTS (derived from the *default* brand
* colour), causing a visible mismatch. This function derives the new fields
* from the actually-saved legacy fields so the preview and form stay coherent.
*
* Only sets a field when the legacy source exists AND the new field is absent.
*/
export const deriveNewFieldsFromLegacy = (saved: Record<string, unknown>): Record<string, unknown> => {
const light = (key: string): string | undefined =>
(saved[key] as { light?: string } | null | undefined)?.light;
const q = light("questionColor");
const b = light("brandColor");
const i = light("inputColor");
return {
...(q && !saved.elementHeadlineColor && { elementHeadlineColor: { light: q } }),
...(q && !saved.elementDescriptionColor && { elementDescriptionColor: { light: q } }),
...(q && !saved.elementUpperLabelColor && { elementUpperLabelColor: { light: q } }),
...(q && !saved.inputTextColor && { inputTextColor: { light: q } }),
...(q && !saved.optionLabelColor && { optionLabelColor: { light: q } }),
...(b && !saved.buttonBgColor && { buttonBgColor: { light: b } }),
...(b && !saved.buttonTextColor && { buttonTextColor: { light: isLight(b) ? "#0f172a" : "#ffffff" } }),
...(i && !saved.optionBgColor && { optionBgColor: { light: i } }),
...(b && !saved.progressIndicatorBgColor && { progressIndicatorBgColor: { light: b } }),
...(b &&
!saved.progressTrackBgColor && { progressTrackBgColor: { light: mixColor(b, "#ffffff", 0.8) } }),
};
};
/** /**
* Builds a complete TProjectStyling object from a single brand color. * Builds a complete TProjectStyling object from a single brand color.
* *

View File

@@ -12,11 +12,18 @@ export function validateInputs<T extends ValidationPair<any>[]>(
for (const [value, schema] of pairs) { for (const [value, schema] of pairs) {
const inputValidation = schema.safeParse(value); const inputValidation = schema.safeParse(value);
if (!inputValidation.success) { if (!inputValidation.success) {
const zodDetails = inputValidation.error.issues
.map((issue) => {
const path = issue?.path?.join(".") ?? "";
return `${path}${issue.message}`;
})
.join("; ");
logger.error( logger.error(
inputValidation.error, inputValidation.error,
`Validation failed for ${JSON.stringify(value).substring(0, 100)} and ${JSON.stringify(schema)}` `Validation failed for ${JSON.stringify(value).substring(0, 100)} and ${JSON.stringify(schema)}`
); );
throw new ValidationError("Validation failed"); throw new ValidationError(`Validation failed: ${zodDetails}`);
} }
parsedData.push(inputValidation.data); parsedData.push(inputValidation.data);
} }

View File

@@ -2153,12 +2153,12 @@
"advanced_styling_field_headline_size_description": "Skaliert den Überschriftentext.", "advanced_styling_field_headline_size_description": "Skaliert den Überschriftentext.",
"advanced_styling_field_headline_weight": "Schriftstärke der Überschrift", "advanced_styling_field_headline_weight": "Schriftstärke der Überschrift",
"advanced_styling_field_headline_weight_description": "Macht den Überschriftentext heller oder fetter.", "advanced_styling_field_headline_weight_description": "Macht den Überschriftentext heller oder fetter.",
"advanced_styling_field_height": "Höhe", "advanced_styling_field_height": "Mindesthöhe",
"advanced_styling_field_indicator_bg": "Indikator-Hintergrund", "advanced_styling_field_indicator_bg": "Indikator-Hintergrund",
"advanced_styling_field_indicator_bg_description": "Färbt den gefüllten Teil des Balkens.", "advanced_styling_field_indicator_bg_description": "Färbt den gefüllten Teil des Balkens.",
"advanced_styling_field_input_border_radius_description": "Rundet die Eingabeecken ab.", "advanced_styling_field_input_border_radius_description": "Rundet die Eingabeecken ab.",
"advanced_styling_field_input_font_size_description": "Skaliert den eingegebenen Text in Eingabefeldern.", "advanced_styling_field_input_font_size_description": "Skaliert den eingegebenen Text in Eingabefeldern.",
"advanced_styling_field_input_height_description": "Steuert die Höhe des Eingabefelds.", "advanced_styling_field_input_height_description": "Legt die Mindesthöhe des Eingabefelds fest.",
"advanced_styling_field_input_padding_x_description": "Fügt links und rechts Abstand hinzu.", "advanced_styling_field_input_padding_x_description": "Fügt links und rechts Abstand hinzu.",
"advanced_styling_field_input_padding_y_description": "Fügt oben und unten Abstand hinzu.", "advanced_styling_field_input_padding_y_description": "Fügt oben und unten Abstand hinzu.",
"advanced_styling_field_input_placeholder_opacity_description": "Blendet den Platzhaltertext aus.", "advanced_styling_field_input_placeholder_opacity_description": "Blendet den Platzhaltertext aus.",
@@ -2221,6 +2221,7 @@
"show_powered_by_formbricks": "\"Powered by Formbricks\"-Signatur anzeigen", "show_powered_by_formbricks": "\"Powered by Formbricks\"-Signatur anzeigen",
"styling_updated_successfully": "Styling erfolgreich aktualisiert", "styling_updated_successfully": "Styling erfolgreich aktualisiert",
"suggest_colors": "Farben vorschlagen", "suggest_colors": "Farben vorschlagen",
"suggested_colors_applied_please_save": "Vorgeschlagene Farben erfolgreich generiert. Drücke \"Speichern\", um die Änderungen zu übernehmen.",
"theme": "Theme", "theme": "Theme",
"theme_settings_description": "Erstelle ein Style-Theme für alle Umfragen. Du kannst für jede Umfrage individuelles Styling aktivieren." "theme_settings_description": "Erstelle ein Style-Theme für alle Umfragen. Du kannst für jede Umfrage individuelles Styling aktivieren."
}, },

View File

@@ -2153,12 +2153,12 @@
"advanced_styling_field_headline_size_description": "Scales the headline text.", "advanced_styling_field_headline_size_description": "Scales the headline text.",
"advanced_styling_field_headline_weight": "Headline Font Weight", "advanced_styling_field_headline_weight": "Headline Font Weight",
"advanced_styling_field_headline_weight_description": "Makes headline text lighter or bolder.", "advanced_styling_field_headline_weight_description": "Makes headline text lighter or bolder.",
"advanced_styling_field_height": "Height", "advanced_styling_field_height": "Minimum Height",
"advanced_styling_field_indicator_bg": "Indicator Background", "advanced_styling_field_indicator_bg": "Indicator Background",
"advanced_styling_field_indicator_bg_description": "Colors the filled portion of the bar.", "advanced_styling_field_indicator_bg_description": "Colors the filled portion of the bar.",
"advanced_styling_field_input_border_radius_description": "Rounds the input corners.", "advanced_styling_field_input_border_radius_description": "Rounds the input corners.",
"advanced_styling_field_input_font_size_description": "Scales the typed text in inputs.", "advanced_styling_field_input_font_size_description": "Scales the typed text in inputs.",
"advanced_styling_field_input_height_description": "Controls the input field height.", "advanced_styling_field_input_height_description": "Controls the minimum height of the input field.",
"advanced_styling_field_input_padding_x_description": "Adds space on the left and right.", "advanced_styling_field_input_padding_x_description": "Adds space on the left and right.",
"advanced_styling_field_input_padding_y_description": "Adds space on the top and bottom.", "advanced_styling_field_input_padding_y_description": "Adds space on the top and bottom.",
"advanced_styling_field_input_placeholder_opacity_description": "Fades the placeholder hint text.", "advanced_styling_field_input_placeholder_opacity_description": "Fades the placeholder hint text.",
@@ -2221,6 +2221,7 @@
"show_powered_by_formbricks": "Show “Powered by Formbricks” Signature", "show_powered_by_formbricks": "Show “Powered by Formbricks” Signature",
"styling_updated_successfully": "Styling updated successfully", "styling_updated_successfully": "Styling updated successfully",
"suggest_colors": "Suggest colors", "suggest_colors": "Suggest colors",
"suggested_colors_applied_please_save": "Suggested colors generated successfully. Press \"Save\" to persist the changes.",
"theme": "Theme", "theme": "Theme",
"theme_settings_description": "Create a style theme for all surveys. You can enable custom styling for each survey." "theme_settings_description": "Create a style theme for all surveys. You can enable custom styling for each survey."
}, },

View File

@@ -2153,12 +2153,12 @@
"advanced_styling_field_headline_size_description": "Escala el texto del titular.", "advanced_styling_field_headline_size_description": "Escala el texto del titular.",
"advanced_styling_field_headline_weight": "Grosor de fuente del titular", "advanced_styling_field_headline_weight": "Grosor de fuente del titular",
"advanced_styling_field_headline_weight_description": "Hace el texto del titular más ligero o más grueso.", "advanced_styling_field_headline_weight_description": "Hace el texto del titular más ligero o más grueso.",
"advanced_styling_field_height": "Altura", "advanced_styling_field_height": "Altura mínima",
"advanced_styling_field_indicator_bg": "Fondo del indicador", "advanced_styling_field_indicator_bg": "Fondo del indicador",
"advanced_styling_field_indicator_bg_description": "Colorea la porción rellena de la barra.", "advanced_styling_field_indicator_bg_description": "Colorea la porción rellena de la barra.",
"advanced_styling_field_input_border_radius_description": "Redondea las esquinas del campo.", "advanced_styling_field_input_border_radius_description": "Redondea las esquinas del campo.",
"advanced_styling_field_input_font_size_description": "Escala el texto escrito en los campos.", "advanced_styling_field_input_font_size_description": "Escala el texto escrito en los campos.",
"advanced_styling_field_input_height_description": "Controla la altura del campo de entrada.", "advanced_styling_field_input_height_description": "Controla la altura mínima del campo de entrada.",
"advanced_styling_field_input_padding_x_description": "Añade espacio a la izquierda y a la derecha.", "advanced_styling_field_input_padding_x_description": "Añade espacio a la izquierda y a la derecha.",
"advanced_styling_field_input_padding_y_description": "Añade espacio en la parte superior e inferior.", "advanced_styling_field_input_padding_y_description": "Añade espacio en la parte superior e inferior.",
"advanced_styling_field_input_placeholder_opacity_description": "Atenúa el texto de sugerencia del marcador de posición.", "advanced_styling_field_input_placeholder_opacity_description": "Atenúa el texto de sugerencia del marcador de posición.",
@@ -2221,6 +2221,7 @@
"show_powered_by_formbricks": "Mostrar firma 'Powered by Formbricks'", "show_powered_by_formbricks": "Mostrar firma 'Powered by Formbricks'",
"styling_updated_successfully": "Estilo actualizado correctamente", "styling_updated_successfully": "Estilo actualizado correctamente",
"suggest_colors": "Sugerir colores", "suggest_colors": "Sugerir colores",
"suggested_colors_applied_please_save": "Colores sugeridos generados correctamente. Pulsa \"Guardar\" para conservar los cambios.",
"theme": "Tema", "theme": "Tema",
"theme_settings_description": "Crea un tema de estilo para todas las encuestas. Puedes activar el estilo personalizado para cada encuesta." "theme_settings_description": "Crea un tema de estilo para todas las encuestas. Puedes activar el estilo personalizado para cada encuesta."
}, },

View File

@@ -2153,12 +2153,12 @@
"advanced_styling_field_headline_size_description": "Ajuste la taille du texte du titre.", "advanced_styling_field_headline_size_description": "Ajuste la taille du texte du titre.",
"advanced_styling_field_headline_weight": "Graisse de police du titre", "advanced_styling_field_headline_weight": "Graisse de police du titre",
"advanced_styling_field_headline_weight_description": "Rend le texte du titre plus léger ou plus gras.", "advanced_styling_field_headline_weight_description": "Rend le texte du titre plus léger ou plus gras.",
"advanced_styling_field_height": "Hauteur", "advanced_styling_field_height": "Hauteur minimale",
"advanced_styling_field_indicator_bg": "Arrière-plan de l'indicateur", "advanced_styling_field_indicator_bg": "Arrière-plan de l'indicateur",
"advanced_styling_field_indicator_bg_description": "Colore la partie remplie de la barre.", "advanced_styling_field_indicator_bg_description": "Colore la partie remplie de la barre.",
"advanced_styling_field_input_border_radius_description": "Arrondit les coins du champ de saisie.", "advanced_styling_field_input_border_radius_description": "Arrondit les coins du champ de saisie.",
"advanced_styling_field_input_font_size_description": "Ajuste la taille du texte saisi dans les champs.", "advanced_styling_field_input_font_size_description": "Ajuste la taille du texte saisi dans les champs.",
"advanced_styling_field_input_height_description": "Contrôle la hauteur du champ de saisie.", "advanced_styling_field_input_height_description": "Contrôle la hauteur minimale du champ de saisie.",
"advanced_styling_field_input_padding_x_description": "Ajoute de l'espace à gauche et à droite.", "advanced_styling_field_input_padding_x_description": "Ajoute de l'espace à gauche et à droite.",
"advanced_styling_field_input_padding_y_description": "Ajoute de l'espace en haut et en bas.", "advanced_styling_field_input_padding_y_description": "Ajoute de l'espace en haut et en bas.",
"advanced_styling_field_input_placeholder_opacity_description": "Atténue le texte d'indication du placeholder.", "advanced_styling_field_input_placeholder_opacity_description": "Atténue le texte d'indication du placeholder.",
@@ -2221,6 +2221,7 @@
"show_powered_by_formbricks": "Afficher la signature «Propulsé par Formbricks»", "show_powered_by_formbricks": "Afficher la signature «Propulsé par Formbricks»",
"styling_updated_successfully": "Style mis à jour avec succès", "styling_updated_successfully": "Style mis à jour avec succès",
"suggest_colors": "Suggérer des couleurs", "suggest_colors": "Suggérer des couleurs",
"suggested_colors_applied_please_save": "Couleurs suggérées générées avec succès. Appuyez sur «Enregistrer» pour conserver les modifications.",
"theme": "Thème", "theme": "Thème",
"theme_settings_description": "Créez un thème de style pour toutes les enquêtes. Vous pouvez activer un style personnalisé pour chaque enquête." "theme_settings_description": "Créez un thème de style pour toutes les enquêtes. Vous pouvez activer un style personnalisé pour chaque enquête."
}, },

View File

@@ -2153,12 +2153,12 @@
"advanced_styling_field_headline_size_description": "Átméretezi a címsor szövegét.", "advanced_styling_field_headline_size_description": "Átméretezi a címsor szövegét.",
"advanced_styling_field_headline_weight": "Címsor betűvastagsága", "advanced_styling_field_headline_weight": "Címsor betűvastagsága",
"advanced_styling_field_headline_weight_description": "Vékonyabbá vagy vastagabbá teszi a címsor szövegét.", "advanced_styling_field_headline_weight_description": "Vékonyabbá vagy vastagabbá teszi a címsor szövegét.",
"advanced_styling_field_height": "Magasság", "advanced_styling_field_height": "Minimális magasság",
"advanced_styling_field_indicator_bg": "Jelző háttere", "advanced_styling_field_indicator_bg": "Jelző háttere",
"advanced_styling_field_indicator_bg_description": "Kiszínezi a sáv kitöltött részét.", "advanced_styling_field_indicator_bg_description": "Kiszínezi a sáv kitöltött részét.",
"advanced_styling_field_input_border_radius_description": "Lekerekíti a beviteli mező sarkait.", "advanced_styling_field_input_border_radius_description": "Lekerekíti a beviteli mező sarkait.",
"advanced_styling_field_input_font_size_description": "Átméretezi a beviteli mezőkbe beírt szöveget.", "advanced_styling_field_input_font_size_description": "Átméretezi a beviteli mezőkbe beírt szöveget.",
"advanced_styling_field_input_height_description": "A beviteli mező magasságát vezérli.", "advanced_styling_field_input_height_description": "A beviteli mező minimális magasságát szabályozza.",
"advanced_styling_field_input_padding_x_description": "Térközt ad hozzá balra és jobbra.", "advanced_styling_field_input_padding_x_description": "Térközt ad hozzá balra és jobbra.",
"advanced_styling_field_input_padding_y_description": "Térközt ad hozzá fent és lent.", "advanced_styling_field_input_padding_y_description": "Térközt ad hozzá fent és lent.",
"advanced_styling_field_input_placeholder_opacity_description": "Elhalványítja a helykitöltő súgószöveget.", "advanced_styling_field_input_placeholder_opacity_description": "Elhalványítja a helykitöltő súgószöveget.",
@@ -2221,6 +2221,7 @@
"show_powered_by_formbricks": "Az „A gépházban: Formbricks” aláírás megjelenítése", "show_powered_by_formbricks": "Az „A gépházban: Formbricks” aláírás megjelenítése",
"styling_updated_successfully": "A stílus sikeresen frissítve", "styling_updated_successfully": "A stílus sikeresen frissítve",
"suggest_colors": "Színek ajánlása", "suggest_colors": "Színek ajánlása",
"suggested_colors_applied_please_save": "A javasolt színek sikeresen generálva. Nyomd meg a \"Mentés\" gombot a változtatások véglegesítéséhez.",
"theme": "Téma", "theme": "Téma",
"theme_settings_description": "Stílustéma létrehozása az összes kérdőívhez. Egyéni stílust engedélyezhet minden egyes kérdőívhez." "theme_settings_description": "Stílustéma létrehozása az összes kérdőívhez. Egyéni stílust engedélyezhet minden egyes kérdőívhez."
}, },

View File

@@ -2153,12 +2153,12 @@
"advanced_styling_field_headline_size_description": "見出しテキストのサイズを調整します。", "advanced_styling_field_headline_size_description": "見出しテキストのサイズを調整します。",
"advanced_styling_field_headline_weight": "見出しのフォントの太さ", "advanced_styling_field_headline_weight": "見出しのフォントの太さ",
"advanced_styling_field_headline_weight_description": "見出しテキストを細くまたは太くします。", "advanced_styling_field_headline_weight_description": "見出しテキストを細くまたは太くします。",
"advanced_styling_field_height": "高さ", "advanced_styling_field_height": "最小の高さ",
"advanced_styling_field_indicator_bg": "インジケーターの背景", "advanced_styling_field_indicator_bg": "インジケーターの背景",
"advanced_styling_field_indicator_bg_description": "バーの塗りつぶし部分に色を付けます。", "advanced_styling_field_indicator_bg_description": "バーの塗りつぶし部分に色を付けます。",
"advanced_styling_field_input_border_radius_description": "入力フィールドの角を丸めます。", "advanced_styling_field_input_border_radius_description": "入力フィールドの角を丸めます。",
"advanced_styling_field_input_font_size_description": "入力フィールド内の入力テキストのサイズを調整します。", "advanced_styling_field_input_font_size_description": "入力フィールド内の入力テキストのサイズを調整します。",
"advanced_styling_field_input_height_description": "入力フィールドの高さを調整します。", "advanced_styling_field_input_height_description": "入力フィールドの最小の高さを制御します。",
"advanced_styling_field_input_padding_x_description": "左右にスペースを追加します。", "advanced_styling_field_input_padding_x_description": "左右にスペースを追加します。",
"advanced_styling_field_input_padding_y_description": "上下にスペースを追加します。", "advanced_styling_field_input_padding_y_description": "上下にスペースを追加します。",
"advanced_styling_field_input_placeholder_opacity_description": "プレースホルダーのヒントテキストを薄くします。", "advanced_styling_field_input_placeholder_opacity_description": "プレースホルダーのヒントテキストを薄くします。",
@@ -2221,6 +2221,7 @@
"show_powered_by_formbricks": "「Powered by Formbricks」署名を表示", "show_powered_by_formbricks": "「Powered by Formbricks」署名を表示",
"styling_updated_successfully": "スタイルを正常に更新しました", "styling_updated_successfully": "スタイルを正常に更新しました",
"suggest_colors": "カラーを提案", "suggest_colors": "カラーを提案",
"suggested_colors_applied_please_save": "推奨カラーが正常に生成されました。変更を保存するには「保存」を押してください。",
"theme": "テーマ", "theme": "テーマ",
"theme_settings_description": "すべてのアンケート用のスタイルテーマを作成します。各アンケートでカスタムスタイルを有効にできます。" "theme_settings_description": "すべてのアンケート用のスタイルテーマを作成します。各アンケートでカスタムスタイルを有効にできます。"
}, },

View File

@@ -2153,12 +2153,12 @@
"advanced_styling_field_headline_size_description": "Schaalt de koptekst.", "advanced_styling_field_headline_size_description": "Schaalt de koptekst.",
"advanced_styling_field_headline_weight": "Letterdikte kop", "advanced_styling_field_headline_weight": "Letterdikte kop",
"advanced_styling_field_headline_weight_description": "Maakt koptekst lichter of vetter.", "advanced_styling_field_headline_weight_description": "Maakt koptekst lichter of vetter.",
"advanced_styling_field_height": "Hoogte", "advanced_styling_field_height": "Minimale hoogte",
"advanced_styling_field_indicator_bg": "Indicatorachtergrond", "advanced_styling_field_indicator_bg": "Indicatorachtergrond",
"advanced_styling_field_indicator_bg_description": "Kleurt het gevulde deel van de balk.", "advanced_styling_field_indicator_bg_description": "Kleurt het gevulde deel van de balk.",
"advanced_styling_field_input_border_radius_description": "Rondt de invoerhoeken af.", "advanced_styling_field_input_border_radius_description": "Rondt de invoerhoeken af.",
"advanced_styling_field_input_font_size_description": "Schaalt de getypte tekst in invoervelden.", "advanced_styling_field_input_font_size_description": "Schaalt de getypte tekst in invoervelden.",
"advanced_styling_field_input_height_description": "Bepaalt de hoogte van het invoerveld.", "advanced_styling_field_input_height_description": "Bepaalt de minimale hoogte van het invoerveld.",
"advanced_styling_field_input_padding_x_description": "Voegt ruimte toe aan de linker- en rechterkant.", "advanced_styling_field_input_padding_x_description": "Voegt ruimte toe aan de linker- en rechterkant.",
"advanced_styling_field_input_padding_y_description": "Voegt ruimte toe aan de boven- en onderkant.", "advanced_styling_field_input_padding_y_description": "Voegt ruimte toe aan de boven- en onderkant.",
"advanced_styling_field_input_placeholder_opacity_description": "Vervaagt de tijdelijke aanwijzingstekst.", "advanced_styling_field_input_placeholder_opacity_description": "Vervaagt de tijdelijke aanwijzingstekst.",
@@ -2221,6 +2221,7 @@
"show_powered_by_formbricks": "Toon 'Powered by Formbricks' handtekening", "show_powered_by_formbricks": "Toon 'Powered by Formbricks' handtekening",
"styling_updated_successfully": "Styling succesvol bijgewerkt", "styling_updated_successfully": "Styling succesvol bijgewerkt",
"suggest_colors": "Kleuren voorstellen", "suggest_colors": "Kleuren voorstellen",
"suggested_colors_applied_please_save": "Voorgestelde kleuren succesvol gegenereerd. Druk op \"Opslaan\" om de wijzigingen te behouden.",
"theme": "Thema", "theme": "Thema",
"theme_settings_description": "Maak een stijlthema voor alle enquêtes. Je kunt aangepaste styling inschakelen voor elke enquête." "theme_settings_description": "Maak een stijlthema voor alle enquêtes. Je kunt aangepaste styling inschakelen voor elke enquête."
}, },

View File

@@ -2153,12 +2153,12 @@
"advanced_styling_field_headline_size_description": "Ajusta o tamanho do texto do título.", "advanced_styling_field_headline_size_description": "Ajusta o tamanho do texto do título.",
"advanced_styling_field_headline_weight": "Peso da fonte do título", "advanced_styling_field_headline_weight": "Peso da fonte do título",
"advanced_styling_field_headline_weight_description": "Torna o texto do título mais leve ou mais negrito.", "advanced_styling_field_headline_weight_description": "Torna o texto do título mais leve ou mais negrito.",
"advanced_styling_field_height": "Altura", "advanced_styling_field_height": "Altura mínima",
"advanced_styling_field_indicator_bg": "Fundo do indicador", "advanced_styling_field_indicator_bg": "Fundo do indicador",
"advanced_styling_field_indicator_bg_description": "Colore a porção preenchida da barra.", "advanced_styling_field_indicator_bg_description": "Colore a porção preenchida da barra.",
"advanced_styling_field_input_border_radius_description": "Arredonda os cantos do campo.", "advanced_styling_field_input_border_radius_description": "Arredonda os cantos do campo.",
"advanced_styling_field_input_font_size_description": "Ajusta o tamanho do texto digitado nos campos.", "advanced_styling_field_input_font_size_description": "Ajusta o tamanho do texto digitado nos campos.",
"advanced_styling_field_input_height_description": "Controla a altura do campo de entrada.", "advanced_styling_field_input_height_description": "Controla a altura mínima do campo de entrada.",
"advanced_styling_field_input_padding_x_description": "Adiciona espaço à esquerda e à direita.", "advanced_styling_field_input_padding_x_description": "Adiciona espaço à esquerda e à direita.",
"advanced_styling_field_input_padding_y_description": "Adiciona espaço na parte superior e inferior.", "advanced_styling_field_input_padding_y_description": "Adiciona espaço na parte superior e inferior.",
"advanced_styling_field_input_placeholder_opacity_description": "Esmaece o texto de dica do placeholder.", "advanced_styling_field_input_placeholder_opacity_description": "Esmaece o texto de dica do placeholder.",
@@ -2221,6 +2221,7 @@
"show_powered_by_formbricks": "Mostrar assinatura 'Powered by Formbricks'", "show_powered_by_formbricks": "Mostrar assinatura 'Powered by Formbricks'",
"styling_updated_successfully": "Estilo atualizado com sucesso", "styling_updated_successfully": "Estilo atualizado com sucesso",
"suggest_colors": "Sugerir cores", "suggest_colors": "Sugerir cores",
"suggested_colors_applied_please_save": "Cores sugeridas geradas com sucesso. Pressione \"Salvar\" para manter as alterações.",
"theme": "Tema", "theme": "Tema",
"theme_settings_description": "Crie um tema de estilo para todas as pesquisas. Você pode ativar estilo personalizado para cada pesquisa." "theme_settings_description": "Crie um tema de estilo para todas as pesquisas. Você pode ativar estilo personalizado para cada pesquisa."
}, },

View File

@@ -2153,12 +2153,12 @@
"advanced_styling_field_headline_size_description": "Ajusta o tamanho do texto do título.", "advanced_styling_field_headline_size_description": "Ajusta o tamanho do texto do título.",
"advanced_styling_field_headline_weight": "Peso da fonte do título", "advanced_styling_field_headline_weight": "Peso da fonte do título",
"advanced_styling_field_headline_weight_description": "Torna o texto do título mais leve ou mais negrito.", "advanced_styling_field_headline_weight_description": "Torna o texto do título mais leve ou mais negrito.",
"advanced_styling_field_height": "Altura", "advanced_styling_field_height": "Altura mínima",
"advanced_styling_field_indicator_bg": "Fundo do indicador", "advanced_styling_field_indicator_bg": "Fundo do indicador",
"advanced_styling_field_indicator_bg_description": "Colore a porção preenchida da barra.", "advanced_styling_field_indicator_bg_description": "Colore a porção preenchida da barra.",
"advanced_styling_field_input_border_radius_description": "Arredonda os cantos do campo.", "advanced_styling_field_input_border_radius_description": "Arredonda os cantos do campo.",
"advanced_styling_field_input_font_size_description": "Ajusta o tamanho do texto digitado nos campos.", "advanced_styling_field_input_font_size_description": "Ajusta o tamanho do texto digitado nos campos.",
"advanced_styling_field_input_height_description": "Controla a altura do campo de entrada.", "advanced_styling_field_input_height_description": "Controla a altura mínima do campo de entrada.",
"advanced_styling_field_input_padding_x_description": "Adiciona espaço à esquerda e à direita.", "advanced_styling_field_input_padding_x_description": "Adiciona espaço à esquerda e à direita.",
"advanced_styling_field_input_padding_y_description": "Adiciona espaço no topo e na base.", "advanced_styling_field_input_padding_y_description": "Adiciona espaço no topo e na base.",
"advanced_styling_field_input_placeholder_opacity_description": "Atenua o texto de sugestão do placeholder.", "advanced_styling_field_input_placeholder_opacity_description": "Atenua o texto de sugestão do placeholder.",
@@ -2221,6 +2221,7 @@
"show_powered_by_formbricks": "Mostrar assinatura 'Powered by Formbricks'", "show_powered_by_formbricks": "Mostrar assinatura 'Powered by Formbricks'",
"styling_updated_successfully": "Estilo atualizado com sucesso", "styling_updated_successfully": "Estilo atualizado com sucesso",
"suggest_colors": "Sugerir cores", "suggest_colors": "Sugerir cores",
"suggested_colors_applied_please_save": "Cores sugeridas geradas com sucesso. Pressiona \"Guardar\" para manter as alterações.",
"theme": "Tema", "theme": "Tema",
"theme_settings_description": "Crie um tema de estilo para todos os inquéritos. Pode ativar estilos personalizados para cada inquérito." "theme_settings_description": "Crie um tema de estilo para todos os inquéritos. Pode ativar estilos personalizados para cada inquérito."
}, },

View File

@@ -2153,12 +2153,12 @@
"advanced_styling_field_headline_size_description": "Scalează textul titlului.", "advanced_styling_field_headline_size_description": "Scalează textul titlului.",
"advanced_styling_field_headline_weight": "Grosime font titlu", "advanced_styling_field_headline_weight": "Grosime font titlu",
"advanced_styling_field_headline_weight_description": "Face textul titlului mai subțire sau mai îngroșat.", "advanced_styling_field_headline_weight_description": "Face textul titlului mai subțire sau mai îngroșat.",
"advanced_styling_field_height": "Înălțime", "advanced_styling_field_height": "Înălțime minimă",
"advanced_styling_field_indicator_bg": "Fundal indicator", "advanced_styling_field_indicator_bg": "Fundal indicator",
"advanced_styling_field_indicator_bg_description": "Colorează partea umplută a barei.", "advanced_styling_field_indicator_bg_description": "Colorează partea umplută a barei.",
"advanced_styling_field_input_border_radius_description": "Rotunjește colțurile câmpurilor de introducere.", "advanced_styling_field_input_border_radius_description": "Rotunjește colțurile câmpurilor de introducere.",
"advanced_styling_field_input_font_size_description": "Scalează textul introdus în câmpuri.", "advanced_styling_field_input_font_size_description": "Scalează textul introdus în câmpuri.",
"advanced_styling_field_input_height_description": "Controlează înălțimea câmpului de introducere.", "advanced_styling_field_input_height_description": "Controlează înălțimea minimă a câmpului de introducere.",
"advanced_styling_field_input_padding_x_description": "Adaugă spațiu la stânga și la dreapta.", "advanced_styling_field_input_padding_x_description": "Adaugă spațiu la stânga și la dreapta.",
"advanced_styling_field_input_padding_y_description": "Adaugă spațiu deasupra și dedesubt.", "advanced_styling_field_input_padding_y_description": "Adaugă spațiu deasupra și dedesubt.",
"advanced_styling_field_input_placeholder_opacity_description": "Estompează textul de sugestie din placeholder.", "advanced_styling_field_input_placeholder_opacity_description": "Estompează textul de sugestie din placeholder.",
@@ -2221,6 +2221,7 @@
"show_powered_by_formbricks": "Afișează semnătura „Powered by Formbricks”", "show_powered_by_formbricks": "Afișează semnătura „Powered by Formbricks”",
"styling_updated_successfully": "Stilizarea a fost actualizată cu succes", "styling_updated_successfully": "Stilizarea a fost actualizată cu succes",
"suggest_colors": "Sugerează culori", "suggest_colors": "Sugerează culori",
"suggested_colors_applied_please_save": "Culorile sugerate au fost generate cu succes. Apasă pe „Salvează” pentru a păstra modificările.",
"theme": "Temă", "theme": "Temă",
"theme_settings_description": "Creează o temă de stil pentru toate sondajele. Poți activa stilizare personalizată pentru fiecare sondaj." "theme_settings_description": "Creează o temă de stil pentru toate sondajele. Poți activa stilizare personalizată pentru fiecare sondaj."
}, },

View File

@@ -2153,12 +2153,12 @@
"advanced_styling_field_headline_size_description": "Масштабирует текст заголовка.", "advanced_styling_field_headline_size_description": "Масштабирует текст заголовка.",
"advanced_styling_field_headline_weight": "Толщина шрифта заголовка", "advanced_styling_field_headline_weight": "Толщина шрифта заголовка",
"advanced_styling_field_headline_weight_description": "Делает текст заголовка тоньше или жирнее.", "advanced_styling_field_headline_weight_description": "Делает текст заголовка тоньше или жирнее.",
"advanced_styling_field_height": "Высота", "advanced_styling_field_height": "Минимальная высота",
"advanced_styling_field_indicator_bg": "Фон индикатора", "advanced_styling_field_indicator_bg": "Фон индикатора",
"advanced_styling_field_indicator_bg_description": "Задаёт цвет заполненной части полосы.", "advanced_styling_field_indicator_bg_description": "Задаёт цвет заполненной части полосы.",
"advanced_styling_field_input_border_radius_description": "Скругляет углы полей ввода.", "advanced_styling_field_input_border_radius_description": "Скругляет углы полей ввода.",
"advanced_styling_field_input_font_size_description": "Масштабирует введённый текст в полях ввода.", "advanced_styling_field_input_font_size_description": "Масштабирует введённый текст в полях ввода.",
"advanced_styling_field_input_height_description": "Определяет высоту поля ввода.", "advanced_styling_field_input_height_description": "Определяет минимальную высоту поля ввода.",
"advanced_styling_field_input_padding_x_description": "Добавляет отступы слева и справа.", "advanced_styling_field_input_padding_x_description": "Добавляет отступы слева и справа.",
"advanced_styling_field_input_padding_y_description": "Добавляет пространство сверху и снизу.", "advanced_styling_field_input_padding_y_description": "Добавляет пространство сверху и снизу.",
"advanced_styling_field_input_placeholder_opacity_description": "Делает текст подсказки менее заметным.", "advanced_styling_field_input_placeholder_opacity_description": "Делает текст подсказки менее заметным.",
@@ -2221,6 +2221,7 @@
"show_powered_by_formbricks": "Показывать подпись «Работает на Formbricks»", "show_powered_by_formbricks": "Показывать подпись «Работает на Formbricks»",
"styling_updated_successfully": "Стили успешно обновлены", "styling_updated_successfully": "Стили успешно обновлены",
"suggest_colors": "Предложить цвета", "suggest_colors": "Предложить цвета",
"suggested_colors_applied_please_save": "Рекомендованные цвета успешно сгенерированы. Нажми «Сохранить», чтобы применить изменения.",
"theme": "Тема", "theme": "Тема",
"theme_settings_description": "Создайте стиль для всех опросов. Вы можете включить индивидуальное оформление для каждого опроса." "theme_settings_description": "Создайте стиль для всех опросов. Вы можете включить индивидуальное оформление для каждого опроса."
}, },

View File

@@ -2153,12 +2153,12 @@
"advanced_styling_field_headline_size_description": "Ändrar storleken på rubriken.", "advanced_styling_field_headline_size_description": "Ändrar storleken på rubriken.",
"advanced_styling_field_headline_weight": "Rubrikens teckentjocklek", "advanced_styling_field_headline_weight": "Rubrikens teckentjocklek",
"advanced_styling_field_headline_weight_description": "Gör rubriktexten tunnare eller fetare.", "advanced_styling_field_headline_weight_description": "Gör rubriktexten tunnare eller fetare.",
"advanced_styling_field_height": "Höjd", "advanced_styling_field_height": "Minsta höjd",
"advanced_styling_field_indicator_bg": "Indikatorns bakgrund", "advanced_styling_field_indicator_bg": "Indikatorns bakgrund",
"advanced_styling_field_indicator_bg_description": "Färglägger den fyllda delen av stapeln.", "advanced_styling_field_indicator_bg_description": "Färglägger den fyllda delen av stapeln.",
"advanced_styling_field_input_border_radius_description": "Rundar av hörnen på inmatningsfält.", "advanced_styling_field_input_border_radius_description": "Rundar av hörnen på inmatningsfält.",
"advanced_styling_field_input_font_size_description": "Ändrar storleken på texten i inmatningsfält.", "advanced_styling_field_input_font_size_description": "Ändrar storleken på texten i inmatningsfält.",
"advanced_styling_field_input_height_description": "Styr höjden på inmatningsfältet.", "advanced_styling_field_input_height_description": "Styr den minsta höjden på inmatningsfältet.",
"advanced_styling_field_input_padding_x_description": "Lägger till utrymme till vänster och höger.", "advanced_styling_field_input_padding_x_description": "Lägger till utrymme till vänster och höger.",
"advanced_styling_field_input_padding_y_description": "Lägger till utrymme upptill och nedtill.", "advanced_styling_field_input_padding_y_description": "Lägger till utrymme upptill och nedtill.",
"advanced_styling_field_input_placeholder_opacity_description": "Tonar ut platshållartexten.", "advanced_styling_field_input_placeholder_opacity_description": "Tonar ut platshållartexten.",
@@ -2221,6 +2221,7 @@
"show_powered_by_formbricks": "Visa 'Powered by Formbricks'-signatur", "show_powered_by_formbricks": "Visa 'Powered by Formbricks'-signatur",
"styling_updated_successfully": "Stiluppdatering lyckades", "styling_updated_successfully": "Stiluppdatering lyckades",
"suggest_colors": "Föreslå färger", "suggest_colors": "Föreslå färger",
"suggested_colors_applied_please_save": "Föreslagna färger har skapats. Tryck på \"Spara\" för att spara ändringarna.",
"theme": "Tema", "theme": "Tema",
"theme_settings_description": "Skapa ett stilmall för alla undersökningar. Du kan aktivera anpassad stil för varje undersökning." "theme_settings_description": "Skapa ett stilmall för alla undersökningar. Du kan aktivera anpassad stil för varje undersökning."
}, },

View File

@@ -2153,12 +2153,12 @@
"advanced_styling_field_headline_size_description": "调整主标题文字大小。", "advanced_styling_field_headline_size_description": "调整主标题文字大小。",
"advanced_styling_field_headline_weight": "标题字体粗细", "advanced_styling_field_headline_weight": "标题字体粗细",
"advanced_styling_field_headline_weight_description": "设置主标题文字的粗细。", "advanced_styling_field_headline_weight_description": "设置主标题文字的粗细。",
"advanced_styling_field_height": "高度", "advanced_styling_field_height": "最小高度",
"advanced_styling_field_indicator_bg": "指示器背景", "advanced_styling_field_indicator_bg": "指示器背景",
"advanced_styling_field_indicator_bg_description": "设置进度条已填充部分的颜色。", "advanced_styling_field_indicator_bg_description": "设置进度条已填充部分的颜色。",
"advanced_styling_field_input_border_radius_description": "设置输入框圆角。", "advanced_styling_field_input_border_radius_description": "设置输入框圆角。",
"advanced_styling_field_input_font_size_description": "调整输入框内文字大小。", "advanced_styling_field_input_font_size_description": "调整输入框内文字大小。",
"advanced_styling_field_input_height_description": "控制输入框高度。", "advanced_styling_field_input_height_description": "设置输入框的最小高度。",
"advanced_styling_field_input_padding_x_description": "增加输入框左右间距。", "advanced_styling_field_input_padding_x_description": "增加输入框左右间距。",
"advanced_styling_field_input_padding_y_description": "为输入框上下添加间距。", "advanced_styling_field_input_padding_y_description": "为输入框上下添加间距。",
"advanced_styling_field_input_placeholder_opacity_description": "调整占位提示文字的透明度。", "advanced_styling_field_input_placeholder_opacity_description": "调整占位提示文字的透明度。",
@@ -2221,6 +2221,7 @@
"show_powered_by_formbricks": "显示“Powered by Formbricks”标识", "show_powered_by_formbricks": "显示“Powered by Formbricks”标识",
"styling_updated_successfully": "样式更新成功", "styling_updated_successfully": "样式更新成功",
"suggest_colors": "推荐颜色", "suggest_colors": "推荐颜色",
"suggested_colors_applied_please_save": "已成功生成推荐配色。请点击“保存”以保留更改。",
"theme": "主题", "theme": "主题",
"theme_settings_description": "为所有问卷创建一个样式主题。你可以为每个问卷启用自定义样式。" "theme_settings_description": "为所有问卷创建一个样式主题。你可以为每个问卷启用自定义样式。"
}, },

View File

@@ -2153,12 +2153,12 @@
"advanced_styling_field_headline_size_description": "調整標題文字的大小。", "advanced_styling_field_headline_size_description": "調整標題文字的大小。",
"advanced_styling_field_headline_weight": "標題字體粗細", "advanced_styling_field_headline_weight": "標題字體粗細",
"advanced_styling_field_headline_weight_description": "讓標題文字變細或變粗。", "advanced_styling_field_headline_weight_description": "讓標題文字變細或變粗。",
"advanced_styling_field_height": "高度", "advanced_styling_field_height": "最小高度",
"advanced_styling_field_indicator_bg": "指示器背景", "advanced_styling_field_indicator_bg": "指示器背景",
"advanced_styling_field_indicator_bg_description": "設定進度條已填滿部分的顏色。", "advanced_styling_field_indicator_bg_description": "設定進度條已填滿部分的顏色。",
"advanced_styling_field_input_border_radius_description": "調整輸入框的圓角。", "advanced_styling_field_input_border_radius_description": "調整輸入框的圓角。",
"advanced_styling_field_input_font_size_description": "調整輸入框內輸入文字的大小。", "advanced_styling_field_input_font_size_description": "調整輸入框內輸入文字的大小。",
"advanced_styling_field_input_height_description": "調整輸入欄位的高度。", "advanced_styling_field_input_height_description": "設定輸入欄位的最小高度。",
"advanced_styling_field_input_padding_x_description": "在左右兩側增加間距。", "advanced_styling_field_input_padding_x_description": "在左右兩側增加間距。",
"advanced_styling_field_input_padding_y_description": "在上方和下方增加間距。", "advanced_styling_field_input_padding_y_description": "在上方和下方增加間距。",
"advanced_styling_field_input_placeholder_opacity_description": "讓提示文字變得更淡。", "advanced_styling_field_input_placeholder_opacity_description": "讓提示文字變得更淡。",
@@ -2221,6 +2221,7 @@
"show_powered_by_formbricks": "顯示「Powered by Formbricks」標記", "show_powered_by_formbricks": "顯示「Powered by Formbricks」標記",
"styling_updated_successfully": "樣式已成功更新", "styling_updated_successfully": "樣式已成功更新",
"suggest_colors": "建議顏色", "suggest_colors": "建議顏色",
"suggested_colors_applied_please_save": "已成功產生建議色彩。請按「儲存」以保存變更。",
"theme": "主題", "theme": "主題",
"theme_settings_description": "為所有調查建立樣式主題。您可以為每個調查啟用自訂樣式。" "theme_settings_description": "為所有調查建立樣式主題。您可以為每個調查啟用自訂樣式。"
}, },

View File

@@ -2,13 +2,26 @@ import { NextRequest, userAgent } from "next/server";
import { logger } from "@formbricks/logger"; import { logger } from "@formbricks/logger";
import { TContactAttributesInput } from "@formbricks/types/contact-attribute"; import { TContactAttributesInput } from "@formbricks/types/contact-attribute";
import { ZEnvironmentId } from "@formbricks/types/environment"; import { ZEnvironmentId } from "@formbricks/types/environment";
import { ResourceNotFoundError } from "@formbricks/types/errors"; import { ResourceNotFoundError, ValidationError } from "@formbricks/types/errors";
import { TJsPersonState } from "@formbricks/types/js"; import { TJsPersonState } from "@formbricks/types/js";
import { responses } from "@/app/lib/api/response"; import { responses } from "@/app/lib/api/response";
import { withV1ApiWrapper } from "@/app/lib/api/with-api-logging"; import { withV1ApiWrapper } from "@/app/lib/api/with-api-logging";
import { getIsContactsEnabled } from "@/modules/ee/license-check/lib/utils"; import { getIsContactsEnabled } from "@/modules/ee/license-check/lib/utils";
import { updateUser } from "./lib/update-user"; import { updateUser } from "./lib/update-user";
const handleError = (err: unknown, url: string): { response: Response } => {
if (err instanceof ResourceNotFoundError) {
return { response: responses.notFoundResponse(err.resourceType, err.resourceId) };
}
if (err instanceof ValidationError) {
return { response: responses.badRequestResponse(err.message, undefined, true) };
}
logger.error({ error: err, url }, "Error in POST /api/v1/client/[environmentId]/user");
return { response: responses.internalServerErrorResponse("Unable to fetch user state", true) };
};
export const OPTIONS = async (): Promise<Response> => { export const OPTIONS = async (): Promise<Response> => {
return responses.successResponse( return responses.successResponse(
{}, {},
@@ -123,16 +136,7 @@ export const POST = withV1ApiWrapper({
response: responses.successResponse(responseJson, true), response: responses.successResponse(responseJson, true),
}; };
} catch (err) { } catch (err) {
if (err instanceof ResourceNotFoundError) { return handleError(err, req.url);
return {
response: responses.notFoundResponse(err.resourceType, err.resourceId),
};
}
logger.error({ error: err, url: req.url }, "Error in POST /api/v1/client/[environmentId]/user");
return {
response: responses.internalServerErrorResponse(err.message ?? "Unable to fetch person state", true),
};
} }
}, },
}); });

View File

@@ -13,22 +13,14 @@ describe("validateAndParseAttributeValue", () => {
} }
}); });
test("converts numbers to string", () => { test("rejects number values (SDK must pass actual strings)", () => {
const result = validateAndParseAttributeValue(42, "string", "testKey"); const result = validateAndParseAttributeValue(42, "string", "testKey");
expect(result.valid).toBe(true); expect(result.valid).toBe(false);
if (result.valid) { if (!result.valid) {
expect(result.parsedValue.value).toBe("42"); expect(result.error.code).toBe("string_type_mismatch");
expect(result.parsedValue.valueNumber).toBeNull(); expect(result.error.params.key).toBe("testKey");
} expect(result.error.params.type).toBe("number");
}); expect(formatValidationError(result.error)).toContain("received a number");
test("converts Date to ISO string", () => {
const date = new Date("2024-01-15T10:30:00.000Z");
const result = validateAndParseAttributeValue(date, "string", "testKey");
expect(result.valid).toBe(true);
if (result.valid) {
expect(result.parsedValue.value).toBe("2024-01-15T10:30:00.000Z");
expect(result.parsedValue.valueDate).toBeNull();
} }
}); });
}); });

View File

@@ -27,15 +27,6 @@ export type TAttributeValidationResult =
error: TAttributeValidationError; error: TAttributeValidationError;
}; };
/**
* Converts any value to a string representation
*/
const convertToString = (value: TRawValue): string => {
if (value instanceof Date) return value.toISOString();
if (typeof value === "number") return String(value);
return value;
};
/** /**
* Gets a human-readable type name for error messages * Gets a human-readable type name for error messages
*/ */
@@ -45,16 +36,28 @@ const getTypeName = (value: TRawValue): string => {
}; };
/** /**
* Validates and parses a string type attribute * Validates and parses a string type attribute.
*/ */
const validateStringType = (value: TRawValue): TAttributeValidationResult => ({ const validateStringType = (value: TRawValue, attributeKey: string): TAttributeValidationResult => {
valid: true, if (typeof value === "string") {
parsedValue: { return {
value: convertToString(value), valid: true,
valueNumber: null, parsedValue: {
valueDate: null, value,
}, valueNumber: null,
}); valueDate: null,
},
};
}
return {
valid: false,
error: {
code: "string_type_mismatch",
params: { key: attributeKey, type: getTypeName(value) },
},
};
};
/** /**
* Validates and parses a number type attribute. * Validates and parses a number type attribute.
@@ -170,13 +173,13 @@ export const validateAndParseAttributeValue = (
): TAttributeValidationResult => { ): TAttributeValidationResult => {
switch (expectedDataType) { switch (expectedDataType) {
case "string": case "string":
return validateStringType(value); return validateStringType(value, attributeKey);
case "number": case "number":
return validateNumberType(value, attributeKey); return validateNumberType(value, attributeKey);
case "date": case "date":
return validateDateType(value, attributeKey); return validateDateType(value, attributeKey);
default: default:
return validateStringType(value); return validateStringType(value, attributeKey);
} }
}; };
@@ -185,6 +188,8 @@ export const validateAndParseAttributeValue = (
* Used for API/SDK responses. * Used for API/SDK responses.
*/ */
const VALIDATION_ERROR_TEMPLATES: Record<string, string> = { const VALIDATION_ERROR_TEMPLATES: Record<string, string> = {
string_type_mismatch:
"Attribute '{key}' expects a string but received a {type}. Pass an actual string value.",
number_type_mismatch: number_type_mismatch:
"Attribute '{key}' expects a number but received a string. Pass an actual number value (e.g., 123 instead of \"123\").", "Attribute '{key}' expects a number but received a string. Pass an actual number value (e.g., 123 instead of \"123\").",
date_invalid: "Attribute '{key}' expects a valid date. Received: Invalid Date", date_invalid: "Attribute '{key}' expects a valid date. Received: Invalid Date",

View File

@@ -11,7 +11,12 @@ import { useTranslation } from "react-i18next";
import { TProjectStyling, ZProjectStyling } from "@formbricks/types/project"; import { TProjectStyling, ZProjectStyling } from "@formbricks/types/project";
import { TSurveyStyling, TSurveyType } from "@formbricks/types/surveys/types"; import { TSurveyStyling, TSurveyType } from "@formbricks/types/surveys/types";
import { previewSurvey } from "@/app/lib/templates"; import { previewSurvey } from "@/app/lib/templates";
import { STYLE_DEFAULTS, getSuggestedColors } from "@/lib/styling/constants"; import {
COLOR_DEFAULTS,
STYLE_DEFAULTS,
deriveNewFieldsFromLegacy,
getSuggestedColors,
} from "@/lib/styling/constants";
import { getFormattedErrorMessage } from "@/lib/utils/helper"; import { getFormattedErrorMessage } from "@/lib/utils/helper";
import { updateProjectAction } from "@/modules/projects/settings/actions"; import { updateProjectAction } from "@/modules/projects/settings/actions";
import { FormStylingSettings } from "@/modules/survey/editor/components/form-styling-settings"; import { FormStylingSettings } from "@/modules/survey/editor/components/form-styling-settings";
@@ -62,11 +67,23 @@ export const ThemeStyling = ({
? Object.fromEntries(Object.entries(savedStyling).filter(([, v]) => v != null)) ? Object.fromEntries(Object.entries(savedStyling).filter(([, v]) => v != null))
: {}; : {};
const legacyFills = deriveNewFieldsFromLegacy(cleanSaved);
const form = useForm<TProjectStyling>({ const form = useForm<TProjectStyling>({
defaultValues: { ...STYLE_DEFAULTS, ...cleanSaved }, defaultValues: { ...STYLE_DEFAULTS, ...legacyFills, ...cleanSaved },
resolver: zodResolver(ZProjectStyling), resolver: zodResolver(ZProjectStyling),
}); });
// Brand color shown in the preview. Only updated when the user triggers
// "Suggest colors", "Save", or "Reset to default" — NOT on every keystroke
// in the brand-color picker. This prevents the loading-spinner / progress
// bar from updating while the user is still picking a colour.
const [previewBrandColor, setPreviewBrandColor] = useState<string>(
(cleanSaved as Partial<TProjectStyling>).brandColor?.light ??
STYLE_DEFAULTS.brandColor?.light ??
COLOR_DEFAULTS.brandColor
);
const [previewSurveyType, setPreviewSurveyType] = useState<TSurveyType>("link"); const [previewSurveyType, setPreviewSurveyType] = useState<TSurveyType>("link");
const [confirmResetStylingModalOpen, setConfirmResetStylingModalOpen] = useState(false); const [confirmResetStylingModalOpen, setConfirmResetStylingModalOpen] = useState(false);
const [confirmSuggestColorsOpen, setConfirmSuggestColorsOpen] = useState(false); const [confirmSuggestColorsOpen, setConfirmSuggestColorsOpen] = useState(false);
@@ -84,6 +101,7 @@ export const ThemeStyling = ({
if (updatedProjectResponse?.data) { if (updatedProjectResponse?.data) {
form.reset({ ...STYLE_DEFAULTS }); form.reset({ ...STYLE_DEFAULTS });
setPreviewBrandColor(STYLE_DEFAULTS.brandColor?.light ?? COLOR_DEFAULTS.brandColor);
toast.success(t("environments.workspace.look.styling_updated_successfully")); toast.success(t("environments.workspace.look.styling_updated_successfully"));
router.refresh(); router.refresh();
} else { } else {
@@ -100,7 +118,10 @@ export const ThemeStyling = ({
form.setValue(key as keyof TProjectStyling, value, { shouldDirty: true }); form.setValue(key as keyof TProjectStyling, value, { shouldDirty: true });
} }
toast.success(t("environments.workspace.look.styling_updated_successfully")); // Commit brand color to the preview now that all derived colours are in sync.
setPreviewBrandColor(brandColor ?? STYLE_DEFAULTS.brandColor?.light ?? COLOR_DEFAULTS.brandColor);
toast.success(t("environments.workspace.look.suggested_colors_applied_please_save"));
setConfirmSuggestColorsOpen(false); setConfirmSuggestColorsOpen(false);
}; };
@@ -113,7 +134,11 @@ export const ThemeStyling = ({
}); });
if (updatedProjectResponse?.data) { if (updatedProjectResponse?.data) {
form.reset({ ...updatedProjectResponse.data.styling }); const saved = updatedProjectResponse.data.styling;
form.reset({ ...saved });
setPreviewBrandColor(
saved?.brandColor?.light ?? STYLE_DEFAULTS.brandColor?.light ?? COLOR_DEFAULTS.brandColor
);
toast.success(t("environments.workspace.look.styling_updated_successfully")); toast.success(t("environments.workspace.look.styling_updated_successfully"));
} else { } else {
const errorMessage = getFormattedErrorMessage(updatedProjectResponse); const errorMessage = getFormattedErrorMessage(updatedProjectResponse);
@@ -249,7 +274,9 @@ export const ThemeStyling = ({
survey={previewSurvey(project.name, t)} survey={previewSurvey(project.name, t)}
project={{ project={{
...project, ...project,
styling: form.watch("allowStyleOverwrite") ? form.watch() : STYLE_DEFAULTS, styling: form.watch("allowStyleOverwrite")
? { ...form.watch(), brandColor: { light: previewBrandColor } }
: STYLE_DEFAULTS,
}} }}
previewType={previewSurveyType} previewType={previewSurveyType}
setPreviewType={setPreviewSurveyType} setPreviewType={setPreviewSurveyType}

View File

@@ -9,7 +9,7 @@ import toast from "react-hot-toast";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { TProjectStyling } from "@formbricks/types/project"; import { TProjectStyling } from "@formbricks/types/project";
import { TSurvey, TSurveyStyling } from "@formbricks/types/surveys/types"; import { TSurvey, TSurveyStyling } from "@formbricks/types/surveys/types";
import { STYLE_DEFAULTS, getSuggestedColors } from "@/lib/styling/constants"; import { STYLE_DEFAULTS, deriveNewFieldsFromLegacy, getSuggestedColors } from "@/lib/styling/constants";
import { FormStylingSettings } from "@/modules/survey/editor/components/form-styling-settings"; import { FormStylingSettings } from "@/modules/survey/editor/components/form-styling-settings";
import { LogoSettingsCard } from "@/modules/survey/editor/components/logo-settings-card"; import { LogoSettingsCard } from "@/modules/survey/editor/components/logo-settings-card";
import { AlertDialog } from "@/modules/ui/components/alert-dialog"; import { AlertDialog } from "@/modules/ui/components/alert-dialog";
@@ -68,10 +68,15 @@ export const StylingView = ({
? Object.fromEntries(Object.entries(localSurvey.styling).filter(([, v]) => v != null)) ? Object.fromEntries(Object.entries(localSurvey.styling).filter(([, v]) => v != null))
: {}; : {};
const projectLegacyFills = deriveNewFieldsFromLegacy(cleanProject);
const surveyLegacyFills = deriveNewFieldsFromLegacy(cleanSurvey);
const form = useForm<TSurveyStyling>({ const form = useForm<TSurveyStyling>({
defaultValues: { defaultValues: {
...STYLE_DEFAULTS, ...STYLE_DEFAULTS,
...projectLegacyFills,
...cleanProject, ...cleanProject,
...surveyLegacyFills,
...cleanSurvey, ...cleanSurvey,
}, },
}); });
@@ -94,7 +99,7 @@ export const StylingView = ({
form.setValue(key as keyof TSurveyStyling, value, { shouldDirty: true }); form.setValue(key as keyof TSurveyStyling, value, { shouldDirty: true });
} }
toast.success(t("environments.workspace.look.styling_updated_successfully")); toast.success(t("environments.workspace.look.suggested_colors_applied_please_save"));
setConfirmSuggestColorsOpen(false); setConfirmSuggestColorsOpen(false);
}; };

View File

@@ -226,7 +226,7 @@ export const InputCombobox: React.FC<InputComboboxProps> = ({
tabIndex={0} tabIndex={0}
aria-controls="options" aria-controls="options"
aria-expanded={open} aria-expanded={open}
className={cn("flex h-full w-full cursor-pointer items-center justify-end bg-white pr-2", { className={cn("flex w-full cursor-pointer items-center justify-end bg-white pr-2 h-10", {
"w-10 justify-center pr-0": withInput && inputType !== "dropdown", "w-10 justify-center pr-0": withInput && inputType !== "dropdown",
"pointer-events-none": isClearing, "pointer-events-none": isClearing,
})}> })}>

View File

@@ -225,10 +225,10 @@ export const PreviewSurvey = ({
)}> )}>
{previewMode === "mobile" && ( {previewMode === "mobile" && (
<> <>
<p className="absolute top-0 left-0 m-2 rounded bg-slate-100 px-2 py-1 text-xs text-slate-400"> <p className="absolute left-0 top-0 m-2 rounded bg-slate-100 px-2 py-1 text-xs text-slate-400">
Preview Preview
</p> </p>
<div className="absolute top-0 right-0 m-2"> <div className="absolute right-0 top-0 m-2">
<ResetProgressButton onClick={resetProgress} /> <ResetProgressButton onClick={resetProgress} />
</div> </div>
<MediaBackground <MediaBackground
@@ -265,7 +265,7 @@ export const PreviewSurvey = ({
</Modal> </Modal>
) : ( ) : (
<div className="flex h-full w-full flex-col justify-center px-1"> <div className="flex h-full w-full flex-col justify-center px-1">
<div className="absolute top-5 left-5"> <div className="absolute left-5 top-5">
{!styling.isLogoHidden && ( {!styling.isLogoHidden && (
<ClientLogo <ClientLogo
environmentId={environment.id} environmentId={environment.id}
@@ -296,7 +296,7 @@ export const PreviewSurvey = ({
</> </>
)} )}
{previewMode === "desktop" && ( {previewMode === "desktop" && (
<div className="flex h-full flex-1 flex-col"> <div className="flex h-full w-full flex-1 flex-col">
<div className="flex h-8 w-full items-center rounded-t-lg bg-slate-100"> <div className="flex h-8 w-full items-center rounded-t-lg bg-slate-100">
<div className="ml-6 flex space-x-2"> <div className="ml-6 flex space-x-2">
<div className="h-3 w-3 rounded-full bg-red-500"></div> <div className="h-3 w-3 rounded-full bg-red-500"></div>
@@ -373,7 +373,7 @@ export const PreviewSurvey = ({
styling={styling} styling={styling}
ContentRef={ContentRef as React.RefObject<HTMLDivElement>} ContentRef={ContentRef as React.RefObject<HTMLDivElement>}
isEditorView> isEditorView>
<div className="absolute top-5 left-5"> <div className="absolute left-5 top-5">
{!styling.isLogoHidden && ( {!styling.isLogoHidden && (
<ClientLogo <ClientLogo
environmentId={environment.id} environmentId={environment.id}

View File

@@ -96,6 +96,7 @@ test.describe("Survey Styling", async () => {
expect(css).toContain("--fb-input-background-color: #eeeeee"); expect(css).toContain("--fb-input-background-color: #eeeeee");
expect(css).toContain("--fb-input-border-color: #cccccc"); expect(css).toContain("--fb-input-border-color: #cccccc");
expect(css).toContain("--fb-input-text-color: #024eff"); expect(css).toContain("--fb-input-text-color: #024eff");
expect(css).toContain("--fb-input-placeholder-color:");
expect(css).toContain("--fb-input-border-radius: 5px"); expect(css).toContain("--fb-input-border-radius: 5px");
expect(css).toContain("--fb-input-height: 50px"); expect(css).toContain("--fb-input-height: 50px");
expect(css).toContain("--fb-input-font-size: 16px"); expect(css).toContain("--fb-input-font-size: 16px");

View File

@@ -127,12 +127,12 @@
--fb-input-font-size: 14px; --fb-input-font-size: 14px;
--fb-input-font-weight: 400; --fb-input-font-weight: 400;
--fb-input-color: #414b5a; --fb-input-color: #414b5a;
--fb-input-placeholder-color: var(--fb-input-color); --fb-input-placeholder-color: var(--fb-input-text-color, var(--fb-input-color));
--fb-input-placeholder-opacity: 0.5; --fb-input-placeholder-opacity: 0.5;
--fb-input-width: 100%; --fb-input-width: 100%;
--fb-input-height: 40px; --fb-input-height: 20px;
--fb-input-padding-x: 16px; --fb-input-padding-x: 8px;
--fb-input-padding-y: 16px; --fb-input-padding-y: 8px;
--fb-input-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05); --fb-input-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
/* ── Progress Bar ──────────────────────────────────────────────────── */ /* ── Progress Bar ──────────────────────────────────────────────────── */
@@ -244,4 +244,4 @@
#fbjs textarea::-webkit-scrollbar-thumb:hover { #fbjs textarea::-webkit-scrollbar-thumb:hover {
background-color: hsl(215.4 16.3% 46.9% / 0.5); background-color: hsl(215.4 16.3% 46.9% / 0.5);
} }

View File

@@ -443,6 +443,39 @@ describe("addCustomThemeToDom", () => {
expect(variables["--fb-button-font-size"]).toBe("1.5rem"); expect(variables["--fb-button-font-size"]).toBe("1.5rem");
}); });
test("should derive input-placeholder-color from inputTextColor when set", () => {
const styling: TSurveyStyling = {
...getBaseProjectStyling(),
questionColor: { light: "#AABBCC" },
inputTextColor: { light: "#112233" },
};
addCustomThemeToDom({ styling });
const styleElement = document.getElementById("formbricks__css__custom") as HTMLStyleElement;
const variables = getCssVariables(styleElement);
// Placeholder should be derived from inputTextColor, not questionColor
expect(variables["--fb-input-placeholder-color"]).toBeDefined();
expect(variables["--fb-placeholder-color"]).toBeDefined();
// Both should be based on inputTextColor (#112233) mixed with white, not questionColor (#AABBCC)
// We can verify by checking the placeholder color doesn't contain the questionColor mix
expect(variables["--fb-input-placeholder-color"]).toBe(variables["--fb-placeholder-color"]);
});
test("should derive input-placeholder-color from questionColor when inputTextColor is not set", () => {
const styling: TSurveyStyling = {
...getBaseProjectStyling(),
questionColor: { light: "#AABBCC" },
};
addCustomThemeToDom({ styling });
const styleElement = document.getElementById("formbricks__css__custom") as HTMLStyleElement;
const variables = getCssVariables(styleElement);
// Placeholder should fall back to questionColor when inputTextColor is not set
expect(variables["--fb-input-placeholder-color"]).toBeDefined();
expect(variables["--fb-placeholder-color"]).toBeDefined();
expect(variables["--fb-input-placeholder-color"]).toBe(variables["--fb-placeholder-color"]);
});
test("should set signature and branding text colors for dark questionColor", () => { test("should set signature and branding text colors for dark questionColor", () => {
const styling = getBaseProjectStyling({ const styling = getBaseProjectStyling({
questionColor: { light: "#202020" }, // A dark color questionColor: { light: "#202020" }, // A dark color

View File

@@ -111,8 +111,10 @@ export const addCustomThemeToDom = ({ styling }: { styling: TProjectStyling | TS
// Backwards-compat: legacy variables still used by some consumers/tests // Backwards-compat: legacy variables still used by some consumers/tests
appendCssVariable("subheading-color", styling.questionColor?.light); appendCssVariable("subheading-color", styling.questionColor?.light);
if (styling.questionColor?.light) { const placeholderBaseColor = styling.inputTextColor?.light ?? styling.questionColor?.light;
appendCssVariable("placeholder-color", mixColor(styling.questionColor.light, "#ffffff", 0.3)); if (placeholderBaseColor) {
appendCssVariable("placeholder-color", mixColor(placeholderBaseColor, "#ffffff", 0.3));
appendCssVariable("input-placeholder-color", mixColor(placeholderBaseColor, "#ffffff", 0.3));
} }
appendCssVariable("border-color", styling.inputBorderColor?.light); appendCssVariable("border-color", styling.inputBorderColor?.light);
@@ -192,8 +194,13 @@ export const addCustomThemeToDom = ({ styling }: { styling: TProjectStyling | TS
} }
// Buttons (Advanced) // Buttons (Advanced)
appendCssVariable("button-bg-color", styling.buttonBgColor?.light); const buttonBg = styling.buttonBgColor?.light ?? styling.brandColor?.light;
appendCssVariable("button-text-color", styling.buttonTextColor?.light); let buttonText = styling.buttonTextColor?.light;
if (buttonText === undefined && buttonBg) {
buttonText = isLight(buttonBg) ? "#0f172a" : "#ffffff";
}
appendCssVariable("button-bg-color", buttonBg);
appendCssVariable("button-text-color", buttonText);
if (styling.buttonBorderRadius !== undefined) if (styling.buttonBorderRadius !== undefined)
appendCssVariable("button-border-radius", formatDimension(styling.buttonBorderRadius)); appendCssVariable("button-border-radius", formatDimension(styling.buttonBorderRadius));
if (styling.buttonHeight !== undefined) if (styling.buttonHeight !== undefined)
@@ -209,7 +216,11 @@ export const addCustomThemeToDom = ({ styling }: { styling: TProjectStyling | TS
// Inputs (Advanced) // Inputs (Advanced)
appendCssVariable("input-background-color", styling.inputBgColor?.light ?? styling.inputColor?.light); appendCssVariable("input-background-color", styling.inputBgColor?.light ?? styling.inputColor?.light);
appendCssVariable("input-text-color", styling.inputTextColor?.light); const inputTextColor = styling.inputTextColor?.light ?? styling.questionColor?.light;
appendCssVariable("input-text-color", inputTextColor);
if (inputTextColor) {
appendCssVariable("input-placeholder-color", mixColor(inputTextColor, "#ffffff", 0.3));
}
if (styling.inputBorderRadius !== undefined) if (styling.inputBorderRadius !== undefined)
appendCssVariable("input-border-radius", formatDimension(styling.inputBorderRadius)); appendCssVariable("input-border-radius", formatDimension(styling.inputBorderRadius));
if (styling.inputHeight !== undefined) if (styling.inputHeight !== undefined)
@@ -225,8 +236,8 @@ export const addCustomThemeToDom = ({ styling }: { styling: TProjectStyling | TS
appendCssVariable("input-shadow", styling.inputShadow); appendCssVariable("input-shadow", styling.inputShadow);
// Options (Advanced) // Options (Advanced)
appendCssVariable("option-bg-color", styling.optionBgColor?.light); appendCssVariable("option-bg-color", styling.optionBgColor?.light ?? styling.inputColor?.light);
appendCssVariable("option-label-color", styling.optionLabelColor?.light); appendCssVariable("option-label-color", styling.optionLabelColor?.light ?? styling.questionColor?.light);
if (styling.optionBorderRadius !== undefined) if (styling.optionBorderRadius !== undefined)
appendCssVariable("option-border-radius", formatDimension(styling.optionBorderRadius)); appendCssVariable("option-border-radius", formatDimension(styling.optionBorderRadius));
if (styling.optionPaddingX !== undefined) if (styling.optionPaddingX !== undefined)
@@ -277,8 +288,15 @@ export const addCustomThemeToDom = ({ styling }: { styling: TProjectStyling | TS
// Implicitly set the progress track border radius to the roundness of the card // Implicitly set the progress track border radius to the roundness of the card
appendCssVariable("progress-track-border-radius", formatDimension(roundness)); appendCssVariable("progress-track-border-radius", formatDimension(roundness));
appendCssVariable("progress-track-bg-color", styling.progressTrackBgColor?.light); appendCssVariable(
appendCssVariable("progress-indicator-bg-color", styling.progressIndicatorBgColor?.light); "progress-track-bg-color",
styling.progressTrackBgColor?.light ??
(styling.brandColor?.light ? mixColor(styling.brandColor.light, "#ffffff", 0.8) : undefined)
);
appendCssVariable(
"progress-indicator-bg-color",
styling.progressIndicatorBgColor?.light ?? styling.brandColor?.light
);
// Close the #fbjs variable block // Close the #fbjs variable block
cssVariables += "}\n"; cssVariables += "}\n";
@@ -304,7 +322,7 @@ export const addCustomThemeToDom = ({ styling }: { styling: TProjectStyling | TS
headlineDecls += " font-size: var(--fb-element-headline-font-size) !important;\n"; headlineDecls += " font-size: var(--fb-element-headline-font-size) !important;\n";
if (styling.elementHeadlineFontWeight !== undefined && styling.elementHeadlineFontWeight !== null) if (styling.elementHeadlineFontWeight !== undefined && styling.elementHeadlineFontWeight !== null)
headlineDecls += " font-weight: var(--fb-element-headline-font-weight) !important;\n"; headlineDecls += " font-weight: var(--fb-element-headline-font-weight) !important;\n";
if (styling.elementHeadlineColor?.light) if (styling.elementHeadlineColor?.light || styling.questionColor?.light)
headlineDecls += " color: var(--fb-element-headline-color) !important;\n"; headlineDecls += " color: var(--fb-element-headline-color) !important;\n";
addRule("#fbjs .label-headline,\n#fbjs .label-headline *", headlineDecls); addRule("#fbjs .label-headline,\n#fbjs .label-headline *", headlineDecls);
@@ -314,7 +332,7 @@ export const addCustomThemeToDom = ({ styling }: { styling: TProjectStyling | TS
descriptionDecls += " font-size: var(--fb-element-description-font-size) !important;\n"; descriptionDecls += " font-size: var(--fb-element-description-font-size) !important;\n";
if (styling.elementDescriptionFontWeight !== undefined && styling.elementDescriptionFontWeight !== null) if (styling.elementDescriptionFontWeight !== undefined && styling.elementDescriptionFontWeight !== null)
descriptionDecls += " font-weight: var(--fb-element-description-font-weight) !important;\n"; descriptionDecls += " font-weight: var(--fb-element-description-font-weight) !important;\n";
if (styling.elementDescriptionColor?.light) if (styling.elementDescriptionColor?.light || styling.questionColor?.light)
descriptionDecls += " color: var(--fb-element-description-color) !important;\n"; descriptionDecls += " color: var(--fb-element-description-color) !important;\n";
addRule("#fbjs .label-description,\n#fbjs .label-description *", descriptionDecls); addRule("#fbjs .label-description,\n#fbjs .label-description *", descriptionDecls);
@@ -324,7 +342,7 @@ export const addCustomThemeToDom = ({ styling }: { styling: TProjectStyling | TS
upperDecls += " font-size: var(--fb-element-upper-label-font-size) !important;\n"; upperDecls += " font-size: var(--fb-element-upper-label-font-size) !important;\n";
if (styling.elementUpperLabelFontWeight !== undefined && styling.elementUpperLabelFontWeight !== null) if (styling.elementUpperLabelFontWeight !== undefined && styling.elementUpperLabelFontWeight !== null)
upperDecls += " font-weight: var(--fb-element-upper-label-font-weight) !important;\n"; upperDecls += " font-weight: var(--fb-element-upper-label-font-weight) !important;\n";
if (styling.elementUpperLabelColor?.light) { if (styling.elementUpperLabelColor?.light || styling.questionColor?.light) {
upperDecls += " color: var(--fb-element-upper-label-color) !important;\n"; upperDecls += " color: var(--fb-element-upper-label-color) !important;\n";
upperDecls += " opacity: var(--fb-element-upper-label-opacity, 1) !important;\n"; upperDecls += " opacity: var(--fb-element-upper-label-opacity, 1) !important;\n";
} }
@@ -332,9 +350,10 @@ export const addCustomThemeToDom = ({ styling }: { styling: TProjectStyling | TS
// --- Buttons --- // --- Buttons ---
let buttonDecls = ""; let buttonDecls = "";
if (styling.buttonBgColor?.light) if (styling.buttonBgColor?.light || styling.brandColor?.light)
buttonDecls += " background-color: var(--fb-button-bg-color) !important;\n"; buttonDecls += " background-color: var(--fb-button-bg-color) !important;\n";
if (styling.buttonTextColor?.light) buttonDecls += " color: var(--fb-button-text-color) !important;\n"; if (styling.buttonTextColor?.light || styling.brandColor?.light)
buttonDecls += " color: var(--fb-button-text-color) !important;\n";
if (styling.buttonBorderRadius !== undefined) if (styling.buttonBorderRadius !== undefined)
buttonDecls += " border-radius: var(--fb-button-border-radius) !important;\n"; buttonDecls += " border-radius: var(--fb-button-border-radius) !important;\n";
if (styling.buttonHeight !== undefined) buttonDecls += " height: var(--fb-button-height) !important;\n"; if (styling.buttonHeight !== undefined) buttonDecls += " height: var(--fb-button-height) !important;\n";
@@ -355,11 +374,11 @@ export const addCustomThemeToDom = ({ styling }: { styling: TProjectStyling | TS
// --- Options --- // --- Options ---
if (styling.optionBorderRadius !== undefined) if (styling.optionBorderRadius !== undefined)
addRule("#fbjs .rounded-option", " border-radius: var(--fb-option-border-radius) !important;\n"); addRule("#fbjs .rounded-option", " border-radius: var(--fb-option-border-radius) !important;\n");
if (styling.optionBgColor?.light) if (styling.optionBgColor?.light || styling.inputColor?.light)
addRule("#fbjs .bg-option-bg", " background-color: var(--fb-option-bg-color) !important;\n"); addRule("#fbjs .bg-option-bg", " background-color: var(--fb-option-bg-color) !important;\n");
let optionLabelDecls = ""; let optionLabelDecls = "";
if (styling.optionLabelColor?.light) if (styling.optionLabelColor?.light || styling.questionColor?.light)
optionLabelDecls += " color: var(--fb-option-label-color) !important;\n"; optionLabelDecls += " color: var(--fb-option-label-color) !important;\n";
if (styling.optionFontSize !== undefined) if (styling.optionFontSize !== undefined)
optionLabelDecls += " font-size: var(--fb-option-font-size) !important;\n"; optionLabelDecls += " font-size: var(--fb-option-font-size) !important;\n";
@@ -385,7 +404,8 @@ export const addCustomThemeToDom = ({ styling }: { styling: TProjectStyling | TS
addRule("#fbjs .border-input-border", " border-color: var(--fb-input-border-color) !important;\n"); addRule("#fbjs .border-input-border", " border-color: var(--fb-input-border-color) !important;\n");
let inputTextDecls = ""; let inputTextDecls = "";
if (styling.inputTextColor?.light) inputTextDecls += " color: var(--fb-input-text-color) !important;\n"; if (styling.inputTextColor?.light || styling.questionColor?.light)
inputTextDecls += " color: var(--fb-input-text-color) !important;\n";
if (styling.inputFontSize !== undefined) if (styling.inputFontSize !== undefined)
inputTextDecls += " font-size: var(--fb-input-font-size) !important;\n"; inputTextDecls += " font-size: var(--fb-input-font-size) !important;\n";
addRule("#fbjs .text-input-text", inputTextDecls); addRule("#fbjs .text-input-text", inputTextDecls);