Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create a theme model that inherits from a base class with serialization information. #5472

Merged
merged 71 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from 54 commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
9e015fc
work for #5094 Create a theme model that inherits from a base class w…
Jan 19, 2024
75420fc
Merge branch 'master' of github.com:surveyjs/survey-creator into issu…
Mar 13, 2024
87acfa7
work for #5094 Create a theme model that inherits from a base class w…
Mar 13, 2024
944cf56
work for #5161
Mar 14, 2024
55aa2d0
Remove the child tab from the root #5161
andrewtelnov Mar 14, 2024
ca36d37
work for #5094
Mar 13, 2024
ff9679b
Merge remote-tracking branch 'origin/issue/5161-PG-subgroup' into iss…
Mar 14, 2024
f77e03e
work for #5094
Mar 15, 2024
244e892
Merge branch 'master' of github.com:surveyjs/survey-creator into issu…
Mar 21, 2024
7d079a3
work for #5094
Mar 21, 2024
ee89d28
work for #5094
Mar 21, 2024
ac04ff1
work for #5094 Create a theme model that inherits from a base class w…
Mar 22, 2024
6480067
work for #5094 Create a theme model that inherits from a base class w…
Mar 29, 2024
96a60b1
Merge branch 'master' of github.com:surveyjs/survey-creator into issu…
Mar 29, 2024
f12b15e
work for #5094 Create a theme model that inherits from a base class w…
Apr 1, 2024
7ca9434
resolve https://github.com/surveyjs/service/issues/1792
Apr 4, 2024
0d9c2b1
work for #5094 Create a theme model that inherits from a base class w…
Apr 5, 2024
dd77f8b
work for #5094 Create a theme model that inherits from a base class w…
Apr 10, 2024
67bdc13
Merge branch 'master' of github.com:surveyjs/survey-creator into issu…
Apr 11, 2024
5431844
work for #5094 Create a theme model that inherits from a base class w…
Apr 11, 2024
6b7291e
work for #5094 Create a theme model that inherits from a base class w…
Apr 12, 2024
6b0c81a
work for #5094 Create a theme model that inherits from a base class w…
Apr 15, 2024
ff0cd90
work for #5094 Create a theme model that inherits from a base class w…
Apr 18, 2024
f0a2df8
work for #5094 Create a theme model that inherits from a base class w…
Apr 18, 2024
0e3279d
work for #5094 Create a theme model that inherits from a base class w…
Apr 19, 2024
527e886
work for #5094 Create a theme model that inherits from a base class w…
Apr 22, 2024
765917a
work for #5094 Create a theme model that inherits from a base class w…
Apr 24, 2024
264b75e
work for #5094 Create a theme model that inherits from a base class w…
Apr 25, 2024
409f0b0
work for #5094 Create a theme model that inherits from a base class w…
Apr 27, 2024
d99e1dc
work for #5094 Create a theme model that inherits from a base class w…
Apr 27, 2024
1ac3f6f
Merge branch 'master' of github.com:surveyjs/survey-creator into issu…
Apr 27, 2024
034c456
work for #5094 Create a theme model that inherits from a base class w…
May 2, 2024
c2ace65
work for #5094 Create a theme model that inherits from a base class w…
May 6, 2024
17d790f
Merge branch 'master' of github.com:surveyjs/survey-creator into issu…
May 6, 2024
7bcbd33
work for #5094 Create a theme model that inherits from a base class w…
May 6, 2024
ec7b377
work for #5094 Create a theme model that inherits from a base class w…
May 7, 2024
5a2cbce
Merge branch 'master' of github.com:surveyjs/survey-creator into issu…
May 7, 2024
1d882d7
work for #5094 Create a theme model that inherits from a base class w…
May 7, 2024
a774bb2
work for #5094 Create a theme model that inherits from a base class w…
May 8, 2024
912ac95
work for #5094 Create a theme model that inherits from a base class w…
May 8, 2024
40d4631
work for #5094 Create a theme model that inherits from a base class w…
May 14, 2024
bbcd2d7
work for #5094 Fix css styles
May 14, 2024
cd1242a
work for #5094 remove comments
May 14, 2024
68bfd80
work for #5094 fix styles for dynamic panel
May 15, 2024
90fdbef
work for #5094 add custome properties
May 16, 2024
5548aa8
work for #5094 Create a theme model that inherits from a base class w…
May 16, 2024
e4ad6fc
work for #5094 Create a theme model that inherits from a base class w…
May 17, 2024
51807c6
Fix issue with onShowingProperty and visibleIf #5094
andrewtelnov May 17, 2024
c42814e
Merge branch 'issue/5094-theme-property-grid-serialization-info' of h…
andrewtelnov May 17, 2024
33a986e
Revert "Fix issue with onShowingProperty and visibleIf #5094"
May 20, 2024
e141895
work for #5094 Create a theme model that inherits from a base class w…
May 20, 2024
e59b762
Merge branch 'master' of github.com:surveyjs/survey-creator into issu…
May 21, 2024
e9e130d
work for #5094 Theme editor settings refactoring
May 21, 2024
e222198
Merge branch 'master' of github.com:surveyjs/survey-creator into issu…
May 22, 2024
f803643
work for #5094 Create a theme model that inherits from a base class w…
May 22, 2024
22bf095
work for #5094 fix visibility property grid editors
May 22, 2024
4707d8e
work for #5094 remove editor.descriptionLocation = "hidden";
May 22, 2024
42ff218
work for #5094 Create a theme model that inherits from a base class w…
May 23, 2024
5181c50
work for #5094 rename ThemeEditorModel -> ThemeTabViewModel
May 23, 2024
64456b3
work for #5094 rename ThemeEditorModel -> ThemeTabViewModel
May 24, 2024
860fdb9
work for #5094 restore checked state for advancedModeSwitcher
May 24, 2024
13d1aa0
work for #5094 renames
May 24, 2024
8ee3e65
work for #5094 renames
May 24, 2024
1a6f883
work for #5094 rename themeMode -> isPaneless
May 27, 2024
dd245e0
work for #5094 fix localization strings
May 28, 2024
cc1aa53
work for #5094 update localization strings
May 28, 2024
eea9f37
Merge branch 'master' of github.com:surveyjs/survey-creator into issu…
May 29, 2024
8004d51
work for #5094 fix russian localization
May 29, 2024
f3b954f
work for #5094 update etalon
May 29, 2024
87ba270
work for #5094 remove comments
May 29, 2024
2917fa4
work for #5094 theme plugin onPropertyGridSurveyCreated event
May 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
439 changes: 439 additions & 0 deletions packages/survey-creator-core/src/components/tabs/header-model.ts

Large diffs are not rendered by default.

1,619 changes: 170 additions & 1,449 deletions packages/survey-creator-core/src/components/tabs/theme-builder.ts

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ if(!ComponentCollection.Instance.getCustomQuestionByName("boxshadowsettings")) {
internal: true,
questionJSON: getQuestionJSON(),
onCreated(question: QuestionCustomModel) {
question.valueFromDataCallback = (value: string | Array<Object>): Array<Object> => typeof value == "string" ? parseBoxShadow(value) : value;
question.valueFromDataCallback = (value: string | Array<Object>): Array<Object> => {
if (typeof value == "undefined") return [{}];
return typeof value == "string" ? parseBoxShadow(value) : value;
};
question.valueToDataCallback = (value: string | Array<Object>): string => !!value ? (typeof value == "string" ? value : createBoxShadow(Array.isArray(value) ? value : [value])) : "";
(<QuestionPanelDynamicModel>question.contentQuestion).panels.forEach(p => p.questions.forEach(q => q.allowRootStyle = false));
},
Expand Down Expand Up @@ -95,7 +98,7 @@ export function createBoxShadowReset(value: string): string {
return createBoxShadow(resetValue);
}

export function parseBoxShadow(value: string): Array<Object> {
export function parseBoxShadow(value: string = ""): Array<Object> {
return value.split(/,(?![^(]*\))/).map(value => {
const color = value.match(/#[a-zA-Z0-9]+|rgba?\(.*?\)/);
const isInset = value.indexOf("inset") > -1;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ComponentCollection, Question, QuestionCompositeModel } from "survey-core";
import { ComponentCollection, JsonObjectProperty, Question, QuestionCompositeModel } from "survey-core";
import { getLocString } from "../../../editorLocalization";
import { assign } from "../../../utils/utils";

function getElementsJSON() {
return [
Expand All @@ -21,23 +22,17 @@ function getElementsJSON() {
},
{
type: "spinedit",
name: "corner",
name: "cornerRadius",
OlgaLarina marked this conversation as resolved.
Show resolved Hide resolved
title: getLocString("theme.cornerRadius"),
titleLocation: "left",
descriptionLocation: "hidden",
unit: "px",
min: 0
},
{
type: "expression",
name: "cornerRadius",
expression: "iif({composite.corner} notempty, {composite.corner} + 'px', '')",
visible: false
}
];
}

if(!ComponentCollection.Instance.getCustomQuestionByName("elementsettings")) {
if (!ComponentCollection.Instance.getCustomQuestionByName("elementsettings")) {
ComponentCollection.Instance.add({
name: "elementsettings",
showInToolbox: false,
Expand All @@ -47,6 +42,9 @@ if(!ComponentCollection.Instance.getCustomQuestionByName("elementsettings")) {
},
onCreated(question) {
},
valueToQuestion(value) {
return JSON.parse(JSON.stringify(value));
},
onValueChanged(question, name, newValue) {
},
});
Expand All @@ -57,37 +55,37 @@ export function updateElementSettingsJSON() {
config.json.elementsJSON = getElementsJSON();
}

export function elementSettingsToCssVariable(question: Question, themeCssVariables: { [index: string]: string }) {
Object.keys(question.value).forEach(key => {
if (key === "corner") return;

const propertyName = `--sjs-${question.name.toLocaleLowerCase()}-${key}`;
if (!question.defaultValue || question.value[key] !== (question as Question).defaultValue[key]) {
themeCssVariables[propertyName] = question.value[key];
export function elementSettingsToCssVariable(value: any = {}, property: JsonObjectProperty, themeCssVariables: { [index: string]: string }) {
Object.keys(value).forEach(key => {
const propertyName = `--sjs-${property.name.toLocaleLowerCase()}-${key}`;
if (!property.defaultValue || value[key] !== property.defaultValue[key]) {
themeCssVariables[propertyName] = value[key];
} else {
themeCssVariables[propertyName] = undefined;
}
});
}

export function elementSettingsFromCssVariable(question: Question, themeCssVariables: { [index: string]: string }, defaultBackcolorVariable: string, defaultHovercolorVariable: string): void {
if (!question) return;
export function elementSettingsFromCssVariable(property: JsonObjectProperty, themeCssVariables: { [index: string]: string }, defaultBackcolorVariableName: string, defaultHovercolorVariableName: string, defaultCornerRadius: number = 4): any {
if (!property) return;

if (!property.defaultValue) property.defaultValue = {};
assign(property.defaultValue, {
backcolor: themeCssVariables[defaultBackcolorVariableName],
hovercolor: themeCssVariables[defaultHovercolorVariableName],
cornerRadius: defaultCornerRadius
});

const compositeQuestion = <QuestionCompositeModel>question;
const elementSettingsFromTheme = Object.keys(themeCssVariables).filter(key => key.indexOf(question.name.toLocaleLowerCase()) !== -1);
const result = { ...property.defaultValue };
const elementSettingsFromTheme = Object.keys(themeCssVariables).filter(key => key.indexOf(property.name.toLocaleLowerCase()) !== -1);

elementSettingsFromTheme.forEach(key => {
const propertyName = key.split("-").pop();

if (propertyName === "cornerRadius" && themeCssVariables[key] !== undefined) {
compositeQuestion.contentPanel.getQuestionByName("corner").value = parseFloat(themeCssVariables[key].toString());
result[propertyName] = parseFloat(themeCssVariables[key].toString());
} else {
compositeQuestion.contentPanel.getQuestionByName(propertyName).value = themeCssVariables[key];
result[propertyName] = themeCssVariables[key];
}
});

if (elementSettingsFromTheme.length === 0) {
(<QuestionCompositeModel>question).contentPanel.getQuestionByName("backcolor").value = defaultBackcolorVariable;
(<QuestionCompositeModel>question).contentPanel.getQuestionByName("hovercolor").value = defaultHovercolorVariable;
}
return result;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ComponentCollection, Question, QuestionCompositeModel, Serializer } from "survey-core";
import { Base, ComponentCollection, JsonObjectProperty, Question, QuestionCompositeModel, Serializer } from "survey-core";
import { getLocString } from "../../../editorLocalization";
import { assign } from "../../../utils/utils";

export const DefaultFonts = [
"Open Sans",
Expand Down Expand Up @@ -65,7 +66,7 @@ function getElementsJSON() {
];
}

if(!ComponentCollection.Instance.getCustomQuestionByName("fontsettings")) {
if (!ComponentCollection.Instance.getCustomQuestionByName("fontsettings")) {
ComponentCollection.Instance.add({
name: "fontsettings",
showInToolbox: false,
Expand All @@ -92,10 +93,14 @@ if(!ComponentCollection.Instance.getCustomQuestionByName("fontsettings")) {
const placeholderColor = question.contentPanel.getQuestionByName("placeholdercolor");
placeholderColor.visible = question.name === "editorFont";
},
valueToQuestion(value) {
return JSON.parse(JSON.stringify(value));
},
onValueChanged(question, name, newValue) {
},
});
}

function syncPropertiesFromComposite(question: Question, propertyName: string, newValue: any) {
const colorQuestion = question.contentPanel.questions[2];
if (propertyName == "allowEmptyColorValue") {
Expand All @@ -108,34 +113,47 @@ export function updateFontSettingsJSON() {
config.json.elementsJSON = getElementsJSON();
}

export function fontsettingsToCssVariable(question: Question, themeCssVariables: { [index: string]: string }) {
Object.keys(question.value).forEach(key => {
const innerQ = (<QuestionCompositeModel>question).contentPanel.getQuestionByName(key);
const propertyName = `--sjs-font-${question.name.toLocaleLowerCase()}-${key}`;
if (!question.defaultValue || question.value[key] !== question.defaultValue[key]) {
themeCssVariables[propertyName] = question.value[key] + (innerQ.unit?.toString() || "");
export function onSerializeFontSettingsValue(obj: Base, propertyName: string) {
const result = { ...obj[propertyName] };
if (result.size != obj.getPropertyByName(propertyName).defaultValue?.size) {
result.size = result.size + "px";
}
return result;
}

export function fontsettingsToCssVariable(value: any = {}, property: JsonObjectProperty, themeCssVariables: { [index: string]: string }) {
Object.keys(value).forEach(key => {
const propertyName = `--sjs-font-${property.name.toLocaleLowerCase()}-${key}`;
if (!property.defaultValue || value[key] !== property.defaultValue[key]) {
themeCssVariables[propertyName] = value[key];
} else {
themeCssVariables[propertyName] = undefined;
}
});
}

export function fontsettingsFromCssVariable(question: Question, themeCssVariables: { [index: string]: string }, defaultColorVariable?: string, defaultPlaceholderColorVariable?: string): void {
if (!question) return;
export function fontsettingsFromCssVariable(property: JsonObjectProperty, themeCssVariables: { [index: string]: string }, defaultColorVariableName?: string, defaultPlaceholderColorVariableName?: string): any {
if (!property) return;

const compositeQuestion = <QuestionCompositeModel>question;
const fontSettingsFromTheme = Object.keys(themeCssVariables).filter(key => key.indexOf(question.name.toLocaleLowerCase()) !== -1);
if (!property.defaultValue) property.defaultValue = {};
assign(property.defaultValue, {
color: themeCssVariables[defaultColorVariableName],
placeholdercolor: !!defaultPlaceholderColorVariableName ? themeCssVariables[defaultPlaceholderColorVariableName] : undefined,
});
if (!property.defaultValue["size"]) {
property.defaultValue["size"] = parseFloat(themeCssVariables["--sjs-font-size"]);
}

const result = { ...property.defaultValue };
const fontSettingsFromTheme = Object.keys(themeCssVariables).filter(key => key.indexOf(property.name.toLocaleLowerCase()) !== -1);
fontSettingsFromTheme.forEach(key => {
const propertyName = key.split("-").pop();
compositeQuestion.contentPanel.getQuestionByName(propertyName).value = themeCssVariables[key];
if (propertyName === "size" && themeCssVariables[key] !== undefined) {
result[propertyName] = parseFloat(themeCssVariables[key].toString());
} else {
result[propertyName] = themeCssVariables[key];
}
});

if (fontSettingsFromTheme.length === 0) {
if (!!defaultColorVariable) {
compositeQuestion.contentPanel.getQuestionByName("color").value = defaultColorVariable;
}
if (!!defaultPlaceholderColorVariable) {
compositeQuestion.contentPanel.getQuestionByName("placeholdercolor").value = defaultPlaceholderColorVariable;
}
}
return result;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { ISurveyPropertiesDefinition, ISurveyPropertyGridDefinition } from "../../question-editor/definition";

const themeModelProperties: ISurveyPropertiesDefinition = {
"theme": {
properties: [
{ name: "header", tab: "header" },

{ name: "--sjs-general-backcolor-dim", tab: "background" },
{ name: "backgroundImage", tab: "background" },
{ name: "backgroundImageFit", tab: "background" },
{ name: "backgroundImageAttachment", tab: "background" },
{ name: "backgroundOpacity", tab: "background" },

{ name: "generalPrimaryColor", tab: "appearancecolor" },
{ name: "panelBackgroundTransparency", tab: "appearancecolor" },
{ name: "questionBackgroundTransparency", tab: "appearancecolor" },
{ name: "--sjs-primary-backcolor", tab: "appearanceprimarycolor" },
{ name: "--sjs-primary-backcolor-dark", tab: "appearanceprimarycolor" },
{ name: "--sjs-primary-backcolor-light", tab: "appearanceprimarycolor" },
{ name: "--sjs-primary-forecolor", tab: "appearanceprimarycolor" },
{ name: "--sjs-primary-forecolor-light", tab: "appearanceprimarycolor" },

{ name: "--sjs-font-family", tab: "appearancefont" },
{ name: "commonFontSize", tab: "appearancefont" },

{ name: "commonScale", tab: "appearanceother" },
{ name: "cornerRadius", tab: "appearanceother" },

{ name: "pageTitle", tab: "appearancepage" },
{ name: "pageDescription", tab: "appearancepage" },

{ name: "questionPanel", tab: "appearancequestion" },
{ name: "--sjs-shadow-small", tab: "appearancequestion" },
{ name: "questionTitle", tab: "appearancequestion" },
{ name: "questionDescription", tab: "appearancequestion" },

{ name: "editorPanel", tab: "appearanceinput" },
{ name: "--sjs-shadow-inner", tab: "appearanceinput" },
{ name: "editorFont", tab: "appearanceinput" },

{ name: "--sjs-border-default", tab: "appearancelines" },
{ name: "--sjs-border-light", tab: "appearancelines" },

],
tabs: [
{ name: "header", index: 100 },
{ name: "background", index: 200 },
{ name: "appearance", index: 300 },
{ name: "appearancelines", parent: "appearance" },
{ name: "appearanceinput", parent: "appearance" },
{ name: "appearancequestion", parent: "appearance" },
{ name: "appearancepage", parent: "appearance" },
{ name: "appearanceother", parent: "appearance" },
{ name: "appearancefont", parent: "appearance" },
{ name: "appearancecolor", parent: "appearance" },
{ name: "appearanceprimarycolor", parent: "appearance" },
]
},
"headersettings@header": {
properties: [
{ name: "headerView" },
{ name: "logoPosition" },
{ name: "surveyTitle" },
{ name: "surveyDescription" },
{ name: "height", tab: "layout" },
{ name: "inheritWidthFrom", tab: "layout" },
{ name: "textAreaWidth", tab: "layout" },

{ name: "backgroundColorSwitch", tab: "background" },
{ name: "backgroundColor", tab: "background" },
{ name: "backgroundImage", tab: "background" },
{ name: "backgroundImageFit", tab: "background" },
{ name: "backgroundImageOpacity", tab: "background" },
{ name: "overlapEnabled", tab: "background" },

{ name: "headerTitle", tab: "header" },
{ name: "headerDescription", tab: "header" },

{ name: "logoPositionX", tab: "positions" },
{ name: "logoPositionY", tab: "positions" },
{ name: "titlePositionX", tab: "positions" },
{ name: "titlePositionY", tab: "positions" },
{ name: "descriptionPositionX", tab: "positions" },
{ name: "descriptionPositionY", tab: "positions" },
],
tabs: [
{ name: "settings" },
{ name: "positions", parent: "settings" },
{ name: "header", parent: "settings" },
{ name: "background", parent: "settings" },
{ name: "layout", parent: "settings" },
]
},
};

export const themeModelPropertyGridDefinition: ISurveyPropertyGridDefinition = {
autoGenerateProperties: true,
classes: themeModelProperties
};

export class ThemeModelEditorDefinition {
public static definition: ISurveyPropertiesDefinition = themeModelProperties;
}
Loading
Loading