survey-creator-react
Version:
Use SurveyJS Creator to create or edit JSON for SurveyJS Form Library.
1,093 lines (1,068 loc) • 139 kB
JavaScript
/*!
* SurveyJS Creator React v2.3.1
* (c) 2015-2025 Devsoft Baltic OÜ - http://surveyjs.io/
* Github: https://github.com/surveyjs/survey-creator
* License: https://surveyjs.io/Licenses#SurveyCreator
*/
import * as React from 'react';
import { createElement, Fragment } from 'react';
import { ReactElementFactory, SurveyElementBase, attachKey2click, SvgIcon, Survey, ReactQuestionFactory, SurveyLocStringViewer, SvgBundleComponent, PopupModal, SurveyActionBar, NotifierComponent, TitleElement, ReactSurveyElementsWrapper, LoadingIndicatorComponent, SurveyPage, Popup, LogoImage, SurveyQuestionElementBase, SurveyQuestion, Scroll, CharacterCounterComponent, SurveyQuestionDropdown, SurveyHeader, List, SurveyQuestionText } from 'survey-react-ui';
import { SurveyCreatorModel, assign, RowViewModel, QuestionAdornerViewModel, QuestionDropdownAdornerViewModel, QuestionImageAdornerViewModel, QuestionRatingAdornerViewModel, PageAdorner, LogoImageViewModel, editorLocalization, ItemValueWrapperViewModel, ImageItemValueWrapperViewModel, MatrixCellWrapperViewModel, SurveyResultsModel, ToolboxToolViewModel, editableStringRendererName, StringEditorViewModelBase, initLogicOperator, PageNavigatorViewModel } from 'survey-creator-core';
export { PropertyGridEditorCollection, SurveyLogic, SurveyLogicUI, SurveyQuestionEditorDefinition, ToolboxToolViewModel, editorLocalization, localization, settings, svgBundle } from 'survey-creator-core';
import * as ReactDOM from 'react-dom';
import { CssClassBuilder, settings, RendererFactory, unwrap, checkLibraryVersion } from 'survey-core';
class TabbedMenuComponent extends SurveyElementBase {
get model() {
return this.props.model;
}
getStateElement() {
return this.model;
}
constructor(props) {
super(props);
this.rootRef = React.createRef();
}
renderElement() {
const items = this.model.renderedActions.map((item) => React.createElement(TabbedMenuItemWrapper, { item: item, key: item.renderedId }));
return (React.createElement("div", { ref: this.rootRef, className: "svc-tabbed-menu", role: "tablist", style: this.model.getRootStyle() }, items));
}
componentDidUpdate(prevProps, prevState) {
super.componentDidUpdate(prevProps, prevState);
const container = this.rootRef.current;
if (!container)
return;
this.model.initResponsivityManager(container);
}
componentDidMount() {
super.componentDidMount();
const container = this.rootRef.current;
if (!container)
return;
this.model.initResponsivityManager(container);
}
componentWillUnmount() {
this.model.resetResponsivityManager();
super.componentWillUnmount();
}
}
class TabbedMenuItemWrapper extends SurveyElementBase {
constructor(props) {
super(props);
this.ref = React.createRef();
}
get item() {
return this.props.item;
}
getStateElement() {
return this.item;
}
renderElement() {
let css = "svc-tabbed-menu-item-container";
if (this.item.css) {
css += " " + this.item.css;
}
css += (!this.item.isVisible ? " sv-action--hidden" : "");
const component = ReactElementFactory.Instance.createElement(this.item.component || "svc-tabbed-menu-item", { item: this.item });
return (React.createElement("span", { key: this.item.id, className: css, ref: this.ref },
React.createElement("div", { className: "sv-action__content" }, component)));
}
componentDidMount() {
super.componentDidMount();
this.item.updateModeCallback = (mode, callback) => {
queueMicrotask(() => {
if (ReactDOM["flushSync"]) {
ReactDOM["flushSync"](() => {
this.item.mode = mode;
});
}
else {
this.item.mode = mode;
}
queueMicrotask(() => {
callback(mode, this.ref.current);
});
});
};
this.item.afterRender();
}
componentWillUnmount() {
super.componentWillUnmount();
this.item.updateModeCallback = undefined;
}
}
class TabbedMenuItemComponent extends SurveyElementBase {
get item() {
return this.props.item;
}
getStateElement() {
return this.item;
}
render() {
const item = this.item;
return (attachKey2click(React.createElement("div", { role: "tab", id: "tab-" + item.id, "aria-selected": item.active, "aria-controls": "scrollableDiv-" + item.id, className: item.getRootCss(), onClick: () => item.action(item) },
item.hasTitle ? React.createElement("span", { className: item.getTitleCss() }, item.title) : null,
item.hasIcon ? React.createElement(SvgIcon, { iconName: item.iconName, className: item.getIconCss(), size: "auto", title: item.tooltip || item.title }) : null)));
}
}
ReactElementFactory.Instance.registerElement("svc-tabbed-menu-item", (props) => {
return React.createElement(TabbedMenuItemComponent, props);
});
class SurveyCreatorComponent extends SurveyElementBase {
constructor(props) {
super(props);
this.rootNode = React.createRef();
}
get creator() {
return this.props.creator;
}
getStateElement() {
return this.creator;
}
get style() {
return this.props.style;
}
componentDidUpdate(prevProps, prevState) {
super.componentDidUpdate(prevProps, prevState);
if (this.creator !== prevProps.creator) {
if (prevProps.creator) {
prevProps.creator.unsubscribeRootElement();
}
if (this.creator && this.rootNode.current) {
this.creator.setRootElement(this.rootNode.current);
}
}
}
componentDidMount() {
super.componentDidMount();
this.creator.setRootElement(this.rootNode.current);
}
componentWillUnmount() {
super.componentWillUnmount();
this.creator.unsubscribeRootElement();
}
renderElement() {
const creator = this.props.creator;
if (creator.isCreatorDisposed)
return null;
const areaClassName = "svc-full-container svc-creator__area svc-flex-column" + (this.props.creator.haveCommercialLicense ? "" : " svc-creator__area--with-banner");
const contentWrapperClassName = "svc-creator__content-wrapper svc-flex-row" + (this.props.creator.isMobileView ? " svc-creator__content-wrapper--footer-toolbar" : "");
const fullContainerClassName = "svc-flex-row svc-full-container" + (" svc-creator__side-bar--" + this.creator.sidebarLocation);
const creatorStyles = {};
assign(creatorStyles, this.style, this.props.creator.themeVariables);
let licenseBanner = null;
if (!this.props.creator.haveCommercialLicense) {
const htmlValue = { __html: this.props.creator.licenseText };
licenseBanner = (React.createElement("div", { className: "svc-creator__banner" },
React.createElement("span", { className: "svc-creator__non-commercial-text", dangerouslySetInnerHTML: htmlValue })));
}
//AM: width unrecognized by react
return (React.createElement("div", { className: this.creator.getRootCss(), ref: this.rootNode, style: creatorStyles },
React.createElement(SvgBundleComponent, null),
React.createElement(PopupModal, null),
React.createElement("div", { className: areaClassName },
React.createElement("div", { className: fullContainerClassName },
React.createElement("div", { className: "svc-flex-column svc-flex-row__element svc-flex-row__element--growing" },
React.createElement("div", { className: "svc-top-bar" },
(creator.showTabs ?
React.createElement("div", { className: "svc-tabbed-menu-wrapper" },
React.createElement(TabbedMenuComponent, { model: creator.tabbedMenu })) : null),
(creator.showToolbar ?
React.createElement("div", { className: "svc-toolbar-wrapper" },
React.createElement(SurveyActionBar, { model: creator.toolbar }))
: null)),
React.createElement("div", { className: contentWrapperClassName },
React.createElement("div", { className: "svc-creator__content-holder svc-flex-column" }, this.renderActiveTab())),
React.createElement("div", { className: "svc-footer-bar" }, (creator.isMobileView ?
React.createElement("div", { className: "svc-toolbar-wrapper" },
React.createElement(SurveyActionBar, { model: creator.footerToolbar }))
: null))),
this.renderSidebar()),
licenseBanner,
React.createElement(NotifierComponent, { notifier: creator.notifier }))));
}
renderActiveTab() {
const creator = this.props.creator;
for (var i = 0; i < creator.tabs.length; i++) {
if (creator.tabs[i].id === creator.activeTab) {
return this.renderCreatorTab(creator.tabs[i]);
}
}
return null;
}
renderCreatorTab(tab) {
if (tab.visible === false) {
return null;
}
const creator = this.props.creator;
const component = !!tab.renderTab
? tab.renderTab()
: ReactElementFactory.Instance.createElement(tab.componentContent, {
creator: creator,
survey: creator.survey,
data: tab.data.model
});
const className = "svc-creator-tab" + (creator.toolboxLocation == "right" ? " svc-creator__toolbox--right" : "");
return (React.createElement("div", { role: "tabpanel", key: tab.id, id: "scrollableDiv-" + tab.id, "aria-labelledby": "tab-" + tab.id, className: className }, component));
}
renderSidebar() {
if (!!this.creator.sidebar) {
return ReactElementFactory.Instance.createElement("svc-side-bar", { model: this.creator.sidebar });
}
else {
return null;
}
}
}
class SurveyCreator extends SurveyCreatorModel {
constructor(options = {}, options2) {
super(options, options2);
}
render(target) {
// eslint-disable-next-line no-console
console.error("The render method is deprecated. Use SurveyCreatorComponent instead.");
}
//ISurveyCreator
createQuestionElement(question) {
return ReactQuestionFactory.Instance.createQuestion(question.isDefaultRendering()
? question.getTemplate()
: question.getComponentName(), {
question: question,
isDisplayMode: question.isReadOnly,
creator: this
});
}
renderError(key, error, cssClasses) {
return (React.createElement("div", { key: key },
React.createElement("span", { className: cssClasses.error.icon, "aria-hidden": "true" }),
React.createElement("span", { className: cssClasses.error.item },
React.createElement(SurveyLocStringViewer, { locStr: error.locText }))));
}
questionTitleLocation() {
return this.survey.questionTitleLocation;
}
questionErrorLocation() {
return this.survey.questionErrorLocation;
}
}
ReactElementFactory.Instance.registerElement("survey-widget", (props) => {
return React.createElement(Survey, props);
});
class CreatorModelElement extends SurveyElementBase {
constructor(props) {
super(props);
this.createModel(props);
}
shouldComponentUpdate(nextProps, nextState) {
const result = super.shouldComponentUpdate(nextProps, nextState);
if (result) {
if (this.needUpdateModel(nextProps)) {
this.createModel(nextProps);
}
}
return result;
}
createModel(props) { }
needUpdateModel(nextProps) {
const names = this.getUpdatedModelProps();
if (!Array.isArray(names))
return true;
for (var i = 0; i < names.length; i++) {
const key = names[i];
if (this.props[key] !== nextProps[key])
return true;
}
return false;
}
getUpdatedModelProps() {
return undefined;
}
}
class RowWrapper extends CreatorModelElement {
constructor(props) {
super(props);
}
createModel(props) {
if (!!this.model) {
this.model.dispose();
}
this.model = new RowViewModel(props.componentData.creator, props.row, null);
}
getUpdatedModelProps() {
return ["row", "componentData"];
}
getStateElement() {
return this.model;
}
componentDidMount() {
super.componentDidMount();
this.model.subscribeElementChanges();
}
componentWillUnmount() {
this.model.unsubscribeElementChanges();
super.componentWillUnmount();
}
render() {
return (React.createElement("div", { key: "svc-row-" + this.props.row.id, className: this.model.cssClasses },
React.createElement("div", { className: "svc-row__drop-indicator svc-row__drop-indicator--top" }),
React.createElement("div", { className: "svc-row__drop-indicator svc-row__drop-indicator--bottom" }),
this.props.element));
}
}
ReactElementFactory.Instance.registerElement("svc-row", (props) => {
return React.createElement(RowWrapper, props);
});
class ReactMouseEvent {
constructor(event) {
this.event = event;
}
stopPropagation() {
this.event.stopPropagation();
//this.event.nativeEvent.stopPropagation();
//this.event.nativeEvent.stopImmediatePropagation();
}
preventDefault() {
this.event.preventDefault();
//this.event.nativeEvent.preventDefault();
}
get cancelBubble() {
//return this.event.cancelBubble;
return false;
}
set cancelBubble(value) {
//this.event.cancelBubble = value;
}
get target() {
return this.event.target;
}
get currentTarget() {
return this.event.currentTarget;
}
get clientX() {
return this.event.clientX;
}
get clientY() {
return this.event.clientY;
}
get offsetX() {
return this.event.nativeEvent.offsetX;
}
get offsetY() {
return this.event.nativeEvent.offsetY;
}
}
class ReactDragEvent extends ReactMouseEvent {
constructor(event) {
super(event);
this.event = event;
}
get dataTransfer() {
return this.event.dataTransfer;
}
}
function QuestionElementContentFunc(props) {
return props.element;
}
const QuestionElementContent = React.memo(QuestionElementContentFunc);
QuestionElementContent.displayName = "QuestionElementContent";
class QuestionAdornerComponent extends CreatorModelElement {
constructor(props) {
super(props);
this.rootRef = React.createRef();
}
createModel(props) {
if (this.model) {
this.model.attachToUI(props.question, this.rootRef.current);
}
else {
this.modelValue = this.createQuestionViewModel(props);
}
}
createQuestionViewModel(props) {
return new QuestionAdornerViewModel(props.componentData, props.question, null);
}
getUpdatedModelProps() {
return ["question", "componentData"];
}
get model() {
return this.modelValue;
}
getStateElement() {
return this.model;
}
renderElement() {
const allowInteractions = this.model.element
.isInteractiveDesignElement;
const titleForCollapsedState = this.renderQuestionTitle();
const content = this.renderContent(allowInteractions);
return (React.createElement("div", { ref: this.rootRef, "data-sv-drop-target-survey-element": this.model.element.name || null, className: this.model.rootCss(), onDoubleClick: e => { allowInteractions && this.model.dblclick(e.nativeEvent); e.stopPropagation(); }, onMouseLeave: e => allowInteractions && this.model.hover(e.nativeEvent, e.currentTarget), onMouseOver: e => allowInteractions && this.model.hover(e.nativeEvent, e.currentTarget) },
titleForCollapsedState,
content));
}
disableTabStop() {
return true;
}
renderContent(allowInteractions) {
var content = this.model.needToRenderContent ? this.renderElementContent() : null;
//if (!allowInteractions) return <>{content}{this.renderFooter()}</>;
return attachKey2click(React.createElement("div", { className: this.model.css(), onClick: (e) => this.model.select(this.model, new ReactMouseEvent(e)) },
React.createElement("div", { className: "svc-question__drop-indicator svc-question__drop-indicator--left" }),
React.createElement("div", { className: "svc-question__drop-indicator svc-question__drop-indicator--right" }),
React.createElement("div", { className: "svc-question__drop-indicator svc-question__drop-indicator--top" }),
React.createElement("div", { className: "svc-question__drop-indicator svc-question__drop-indicator--bottom" }),
allowInteractions ? this.renderHeader() : null,
content,
this.model.needToRenderContent ? this.renderFooter() : null), undefined, { disableTabStop: this.disableTabStop() });
}
renderHeader() {
return ReactElementFactory.Instance.createElement("svc-question-header", { model: this.model });
}
renderFooter() {
const allowInteractions = this.model.element
.isInteractiveDesignElement;
return allowInteractions ? ReactElementFactory.Instance.createElement("svc-question-footer", { className: "svc-question__content-actions", model: this.model }) : null;
}
renderCarryForwardBanner() {
if (!this.model.isBannerShowing)
return null;
return ReactElementFactory.Instance.createElement("svc-question-banner", this.model.createBannerParams());
}
renderQuestionTitle() {
if (!this.model.showHiddenTitle)
return null;
const element = this.model.element;
return (React.createElement("div", { ref: node => node && (!this.model.renderedCollapsed ?
node.setAttribute("inert", "") : node.removeAttribute("inert")), className: this.model.cssCollapsedHiddenHeader }, (element.hasTitle ?
React.createElement(TitleElement, { element: element }) :
React.createElement("div", { className: this.model.cssCollapsedHiddenTitle },
React.createElement("span", { className: "svc-fake-title" }, element.name)))));
}
renderElementContent() {
return (React.createElement(React.Fragment, null,
React.createElement(QuestionElementContent, { element: this.props.element }),
this.renderElementPlaceholder(),
this.renderCarryForwardBanner()));
}
componentDidMount() {
super.componentDidMount();
this.model.attachToUI(this.props.question, this.rootRef.current);
}
renderElementPlaceholder() {
if (!this.model.isEmptyElement) {
return null;
}
return (React.createElement("div", { className: "svc-panel__placeholder_frame-wrapper" },
React.createElement("div", { className: "svc-panel__placeholder_frame" },
React.createElement("div", { className: "svc-panel__placeholder" }, this.model.placeholderText))));
}
componentWillUnmount() {
super.componentWillUnmount();
this.model.detachFromUI();
}
}
ReactElementFactory.Instance.registerElement("svc-question", (props) => {
return React.createElement(QuestionAdornerComponent, props);
});
class QuestionWrapperHeader extends React.Component {
render() {
if (!this.props.model.allowDragging)
return null;
return (React.createElement("div", { className: "svc-question__drag-area", onPointerDown: (event) => this.props.model.onPointerDown(event) },
React.createElement(SvgIcon, { className: "svc-question__drag-element", size: "auto", iconName: "icon-drag-area-indicator_24x16" }),
React.createElement("div", { className: "svc-question__top-actions" },
React.createElement(SurveyActionBar, { model: this.props.model.topActionContainer, handleClick: false }))));
}
}
ReactElementFactory.Instance.registerElement("svc-question-header", (props) => {
return React.createElement(QuestionWrapperHeader, props);
});
class QuestionWrapperFooter extends React.Component {
render() {
return (React.createElement("div", { className: this.props.className, onFocus: (e) => this.props.model.select(this.props.model, new ReactMouseEvent(e)) },
React.createElement(SurveyActionBar, { model: this.props.model.actionContainer, handleClick: false })));
}
}
ReactElementFactory.Instance.registerElement("svc-question-footer", (props) => {
return React.createElement(QuestionWrapperFooter, props);
});
class ActionButton extends SurveyElementBase {
renderElement() {
const classes = new CssClassBuilder()
.append(this.props.classes)
.append("svc-action-button")
.append("svc-action-button--selected", !!this.props.selected)
.append("svc-action-button--disabled", !!this.props.disabled)
.toString();
if (this.props.iconName) {
return this.renderIcon(classes);
}
return this.renderButtonText(classes);
}
renderButtonText(classes) {
if (this.props.disabled) {
return React.createElement("span", { className: classes }, this.props.text);
}
return (React.createElement(React.Fragment, null, attachKey2click(React.createElement("span", { role: "button", className: classes, onClick: (e) => {
if (!this.props.allowBubble) {
e.stopPropagation();
}
this.props.click();
}, title: this.props.title }, this.props.text))));
}
renderIcon(classes) {
classes += " svc-action-button--icon";
if (this.props.disabled) {
return React.createElement("span", { className: classes },
React.createElement(SvgIcon, { size: "auto", iconName: this.props.iconName }));
}
return (React.createElement(React.Fragment, null, attachKey2click(React.createElement("span", { className: classes, onClick: (e) => {
if (!this.props.allowBubble) {
e.stopPropagation();
}
this.props.click();
}, title: this.props.title },
React.createElement(SvgIcon, { size: "auto", iconName: this.props.iconName })))));
}
}
ReactElementFactory.Instance.registerElement("svc-action-button", (props) => { return React.createElement(ActionButton, props); });
class QuestionBanner extends React.Component {
render() {
return (React.createElement("div", { className: "svc-carry-forward-panel-wrapper" },
React.createElement("div", { className: "svc-carry-forward-panel" },
React.createElement("span", null,
this.props.text,
" "),
React.createElement("span", { className: "svc-carry-forward-panel__link" },
React.createElement(ActionButton, { click: () => this.props.onClick(), text: this.props.actionText })))));
}
}
ReactElementFactory.Instance.registerElement("svc-question-banner", (props) => {
return React.createElement(QuestionBanner, props);
});
class QuestionDropdownAdornerComponent extends QuestionAdornerComponent {
constructor(props) {
super(props);
}
createQuestionViewModel(props) {
return new QuestionDropdownAdornerViewModel(props.componentData, props.question, null);
}
get dropdownModel() {
return this.model;
}
get question() {
return this.dropdownModel.question;
}
renderElementPlaceholder() {
const textStyle = this.question.textStyle;
return (React.createElement("div", { className: "svc-question__dropdown-choices--wrapper" },
React.createElement("div", null,
React.createElement("div", { className: "svc-question__dropdown-choices" }, (this.dropdownModel.getRenderedItems() || []).map((item, index) => (React.createElement("div", { className: this.dropdownModel.getChoiceCss(), key: `editable_choice_${index}` }, ReactSurveyElementsWrapper.wrapItemValue(this.question.survey, ReactElementFactory.Instance.createElement(this.dropdownModel.itemComponent, {
key: item.value,
question: this.question,
cssClasses: this.question.cssClasses,
isDisplayMode: true,
item: item,
textStyle: textStyle,
index: index,
isChecked: this.question.value === item.value
}), this.question, item))))),
this.dropdownModel.needToCollapse ?
React.createElement(ActionButton, { click: this.dropdownModel.switchCollapse, text: this.dropdownModel.getButtonText(), allowBubble: true }) :
null)));
}
}
ReactElementFactory.Instance.registerElement("svc-dropdown-question", (props) => {
return React.createElement(QuestionDropdownAdornerComponent, props);
});
class QuestionImageAdornerComponent extends QuestionAdornerComponent {
createQuestionViewModel(props) {
return new QuestionImageAdornerViewModel(props.componentData, props.question, null);
}
get imageModel() {
return this.model;
}
renderHeader() {
return (React.createElement(React.Fragment, null,
React.createElement("input", { type: "file", "aria-hidden": "true", tabIndex: -1, accept: this.imageModel.acceptedTypes, className: "svc-choose-file-input", style: {
position: "absolute",
opacity: 0,
width: "1px",
height: "1px",
overflow: "hidden"
} }),
super.renderHeader()));
}
renderLoadingPlaceholder() {
return (React.createElement("div", { className: "svc-image-question__loading-placeholder" },
React.createElement("div", { className: "svc-image-question__loading" },
React.createElement(LoadingIndicatorComponent, null))));
}
renderChooseButton() {
return (React.createElement("div", { className: "svc-image-question-controls" }, this.model.allowEdit ? attachKey2click(React.createElement("span", { className: "svc-context-button", onClick: () => this.imageModel.chooseFile(this.imageModel) },
React.createElement(SvgIcon, { size: "auto", iconName: "icon-choosefile" }))) : null));
}
renderElementPlaceholder() {
return this.imageModel.isUploading ? this.renderLoadingPlaceholder() : this.renderChooseButton();
}
getStateElements() {
return [this.model, this.imageModel.filePresentationModel];
}
renderElementContent() {
if (this.imageModel.isEmptyImageLink) {
const fileQuestion = ReactQuestionFactory.Instance.createQuestion("file", {
creator: this.imageModel.question.survey,
isDisplayMode: false,
question: this.imageModel.filePresentationModel
});
return (React.createElement(React.Fragment, null, fileQuestion));
}
else {
return (React.createElement(React.Fragment, null,
this.props.element,
this.renderElementPlaceholder()));
}
}
}
ReactElementFactory.Instance.registerElement("svc-image-question", (props) => {
return React.createElement(QuestionImageAdornerComponent, props);
});
class QuestionRatingAdornerComponent extends CreatorModelElement {
createModel(props) {
this.modelValue = this.createQuestionViewModel(props);
}
createQuestionViewModel(props) {
return new QuestionRatingAdornerViewModel(props.componentData, props.question, null);
}
getUpdatedModelProps() {
return ["question", "componentData"];
}
get ratingModel() {
return this.model;
}
get model() {
return this.modelValue;
}
getStateElement() {
return this.model;
}
renderElement() {
const model = this.ratingModel;
return (React.createElement(React.Fragment, null,
React.createElement("div", { className: "svc-rating-question-content" },
React.createElement("div", { className: model.controlsClassNames },
model.allowRemove ? attachKey2click(React.createElement("span", { role: "button", className: model.removeClassNames, "aria-label": model.removeTooltip, onClick: () => model.removeItem(model) },
React.createElement(SvgIcon, { size: "auto", iconName: "icon-remove_16x16", title: model.removeTooltip }))) : null,
model.allowAdd ? attachKey2click(React.createElement("span", { role: "button", className: model.addClassNames, "aria-label": model.addTooltip, onClick: () => model.addItem(model) },
React.createElement(SvgIcon, { size: "auto", iconName: "icon-add_16x16", title: model.addTooltip }))) : null),
this.props.element)));
}
}
ReactElementFactory.Instance.registerElement("svc-rating-question", (props) => {
return React.createElement(QuestionRatingAdornerComponent, props);
});
ReactElementFactory.Instance.registerElement("svc-rating-question-content", (props) => {
return React.createElement(QuestionRatingAdornerComponent, props);
});
class QuestionWidgetAdornerComponent extends QuestionAdornerComponent {
createQuestionViewModel(props) {
return new QuestionAdornerViewModel(props.componentData, props.question, null);
}
get widgetModel() {
return this.model;
}
renderElementContent() {
return (React.createElement("div", { className: "svc-widget__content" }, this.props.element));
}
}
ReactElementFactory.Instance.registerElement("svc-widget-question", (props) => {
return React.createElement(QuestionWidgetAdornerComponent, props);
});
class CellQuestionAdornerComponent extends CreatorModelElement {
createModel(props) {
this.model = new QuestionAdornerViewModel(props.componentData, props.question, null);
}
getStateElement() {
return this.model;
}
getUpdatedModelProps() {
return ["question", "componentData"];
}
render() {
return (React.createElement(React.Fragment, null,
React.createElement("div", { "data-sv-drop-target-survey-element": this.model.element.name, className: "svc-question__adorner" },
React.createElement("div", { className: " svc-question__content--in-popup svc-question__content" }, this.props.element))));
}
}
ReactElementFactory.Instance.registerElement("svc-cell-question", (props) => {
return React.createElement(CellQuestionAdornerComponent, props);
});
class CellQuestionDropdownAdornerComponent extends CreatorModelElement {
createModel(props) {
this.model = new QuestionAdornerViewModel(props.componentData, props.question, null);
}
getUpdatedModelProps() {
return ["question", "componentData"];
}
getStateElement() {
return this.model;
}
render() {
const question = this.props.question;
const textStyle = this.props.question.textStyle;
return (React.createElement(React.Fragment, null,
React.createElement("div", { "data-sv-drop-target-survey-element": this.model.element.name, className: "svc-question__adorner" },
React.createElement("div", { className: " svc-question__content--in-popup svc-question__content" },
this.props.element,
React.createElement("div", { className: "svc-question__dropdown-choices" }, question.visibleChoices.map((item, index) => (React.createElement("div", { className: "svc-question__dropdown-choice", key: `editable_choice_${index}` }, ReactSurveyElementsWrapper.wrapItemValue(question.survey, ReactElementFactory.Instance.createElement("survey-radiogroup-item", {
question: question,
cssClasses: question.cssClasses,
isDisplayMode: true,
item: item,
textStyle: textStyle,
index: index,
isChecked: question.value === item.value
}), question, item)))))))));
}
}
ReactElementFactory.Instance.registerElement("svc-cell-dropdown-question", (props) => {
return React.createElement(CellQuestionDropdownAdornerComponent, props);
});
const PageElementContent = React.memo(({ page, survey, creator }) => {
return React.createElement(SurveyPage, { page: page, survey: survey, creator: creator });
});
PageElementContent.displayName = "PageElementContent";
class CreatorSurveyPageComponent extends CreatorModelElement {
constructor(props) {
super(props);
this.rootRef = React.createRef();
}
createModel(props) {
if (this.model) {
this.model.attachToUI(props.page, this.rootRef.current);
}
this.model = this.createPageAdorner(props.creator, props.page);
this.model.isGhost = this.props.isGhost;
}
createPageAdorner(creator, page) {
return new PageAdorner(creator, page);
}
shouldComponentUpdate(nextProps, nextState) {
const res = super.shouldComponentUpdate(nextProps, nextState);
if (this.model) {
this.model.isGhost = this.props.isGhost;
}
return res;
}
componentDidUpdate(prevProps, prevState) {
super.componentDidUpdate(prevProps, prevState);
}
getUpdatedModelProps() {
return ["creator", "page"];
}
getStateElement() {
return this.model;
}
componentDidMount() {
super.componentDidMount();
this.model.attachToUI(this.props.page, this.rootRef.current);
this.model.isGhost = this.props.isGhost;
}
componentWillUnmount() {
super.componentWillUnmount();
this.model.detachFromUI();
}
canRender() {
return super.canRender();
}
renderElement() {
if (!this.props.page)
return null;
return (attachKey2click(React.createElement("div", { ref: this.rootRef, id: this.props.page.id, "data-sv-drop-target-survey-page": this.model.dropTargetName, className: "svc-page__content " + this.model.css, onClick: (e) => {
return this.model.select(this.model, new ReactMouseEvent(e));
}, onDoubleClick: e => this.model.dblclick(e.nativeEvent), onMouseLeave: (e) => this.model.hover(e.nativeEvent, e.currentTarget), onMouseOver: (e) => this.model.hover(e.nativeEvent, e.currentTarget) },
React.createElement("div", { className: "svc-question__drop-indicator svc-question__drop-indicator--top" }),
React.createElement("div", { className: "svc-question__drop-indicator svc-question__drop-indicator--bottom" }),
this.renderContent(),
this.renderPlaceholder(),
this.renderHeader(),
this.renderFooter())));
}
renderPlaceholder() {
if (!this.model.showPlaceholder)
return null;
return (React.createElement("div", { className: "svc-page__placeholder_frame" },
React.createElement("div", { className: "svc-panel__placeholder_frame" },
React.createElement("div", { className: "svc-panel__placeholder" }, this.model.placeholderText))));
}
renderContent() {
if (!this.model.needRenderContent) {
return React.createElement("div", { className: "svc-page__loading-content" },
React.createElement(LoadingIndicatorComponent, null));
}
return (React.createElement(PageElementContent, { page: this.props.page, survey: this.props.survey, creator: this.props.creator }));
}
renderHeader() {
const actions = (React.createElement("div", { className: "svc-page__content-actions" },
React.createElement(SurveyActionBar, { model: this.model.actionContainer }),
(this.model.topActionContainer.hasActions ? React.createElement(SurveyActionBar, { model: this.model.topActionContainer }) : null)));
if (this.model.isGhost || !this.model.allowDragging) {
return actions;
}
return (React.createElement("div", { className: "svc-question__drag-area", onPointerDown: (event) => this.model.onPointerDown(event) },
React.createElement(SvgIcon, { className: "svc-question__drag-element", size: "auto", iconName: "icon-drag-area-indicator_24x16" }),
actions));
}
renderFooter() {
return React.createElement(SurveyActionBar, { model: this.model.footerActionsBar });
}
}
ReactElementFactory.Instance.registerElement("svc-page", (props) => {
return React.createElement(CreatorSurveyPageComponent, props);
});
class AddQuestionButtonComponent extends SurveyElementBase {
get model() {
return this.props.item.data;
}
renderTypeSelector() {
const questionTypeSelectorModel = this.model.questionTypeSelectorModel;
return attachKey2click(React.createElement("button", { type: "button", onClick: (e) => {
e.stopPropagation();
questionTypeSelectorModel.action();
}, className: "svc-element__question-type-selector", title: this.model.addNewQuestionText, role: "button" },
React.createElement("span", { className: "svc-element__question-type-selector-icon" },
React.createElement(SvgIcon, { iconName: questionTypeSelectorModel.iconName, size: "auto", title: this.model.addNewQuestionText })),
this.props.renderPopup === undefined || this.props.renderPopup ?
React.createElement(Popup, { model: questionTypeSelectorModel.popupModel })
: null));
}
renderElement() {
const addButtonClass = this.props.buttonClass || "svc-btn";
return React.createElement(React.Fragment, null,
attachKey2click(React.createElement("div", { className: "svc-element__add-new-question " + addButtonClass, onClick: (e) => {
e.stopPropagation();
this.model.addNewQuestion(this.model, new ReactMouseEvent(e));
}, onMouseOver: (e) => this.model.hoverStopper && this.model.hoverStopper(e.nativeEvent, e.currentTarget) },
React.createElement(SvgIcon, { className: "svc-panel__add-new-question-icon", iconName: "icon-add_24x24", size: "auto" }),
React.createElement("span", { className: "svc-add-new-item-button__text" }, this.model.addNewQuestionText),
this.props.renderPopup !== false ? this.renderTypeSelector() : null)),
this.props.renderPopup === false ? this.renderTypeSelector() : null);
}
}
ReactElementFactory.Instance.registerElement("svc-add-new-question-btn", (props) => {
return React.createElement(AddQuestionButtonComponent, props);
});
class PanelAdornerComponent extends QuestionAdornerComponent {
renderElementPlaceholder() {
if (!this.model.isEmptyElement) {
return null;
}
return (React.createElement("div", { className: "svc-panel__placeholder_frame-wrapper" },
React.createElement("div", { className: "svc-panel__placeholder_frame" },
React.createElement("div", { className: "svc-panel__placeholder" }, this.model.placeholderText),
this.model.showAddQuestionButton ? attachKey2click(React.createElement("div", { className: "svc-panel__add-new-question svc-action-button", onClick: (e) => {
e.stopPropagation();
this.model.addNewQuestion();
} },
React.createElement(SvgIcon, { className: "svc-panel__add-new-question-icon", iconName: "icon-add_24x24", size: "auto" }),
React.createElement("span", { className: "svc-add-new-item-button__text" }, this.model.addNewQuestionText))) : null)));
}
disableTabStop() {
return true;
}
renderFooter() {
return (React.createElement(React.Fragment, null,
!this.model.isEmptyElement && this.model.element.isPanel && this.model.showAddQuestionButton ? (React.createElement("div", { className: "svc-panel__add-new-question-container" },
React.createElement("div", { className: "svc-panel__question-type-selector-popup" },
React.createElement(Popup, { model: this.model.questionTypeSelectorModel.popupModel })),
React.createElement("div", { className: "svc-panel__add-new-question-wrapper" },
React.createElement(AddQuestionButtonComponent, { item: { data: this.model }, buttonClass: "svc-action-button", renderPopup: false })))) : null,
super.renderFooter()));
}
}
ReactElementFactory.Instance.registerElement("svc-panel", (props) => {
return React.createElement(PanelAdornerComponent, props);
});
class LogoImageComponent extends CreatorModelElement {
constructor(props) {
super(props);
this.rootRef = React.createRef();
}
createModel(props) {
let prevRoot = null;
if (!!this.model) {
prevRoot = this.model.root;
}
this.model = new LogoImageViewModel(props.data, prevRoot);
}
getUpdatedModelProps() {
return ["data"];
}
getStateElement() {
return this.model;
}
componentDidMount() {
super.componentDidMount();
this.model.root = this.rootRef.current;
}
renderChooseButton() {
return attachKey2click(React.createElement("span", { className: "svc-context-button", onClick: () => this.model.chooseFile(this.model) },
React.createElement(SvgIcon, { size: "auto", iconName: "icon-choosefile" })));
}
renderClearButton() {
return attachKey2click(React.createElement("span", { className: "svc-context-button svc-context-button--danger", onClick: () => this.model.remove(this.model) },
React.createElement(SvgIcon, { size: "auto", iconName: "icon-clear" })));
}
renderButtons() {
return (React.createElement("div", { className: "svc-context-container svc-logo-image-controls" },
this.renderChooseButton(),
this.renderClearButton()));
}
renderImage() {
return React.createElement("div", { className: this.model.containerCss },
this.renderButtons(),
React.createElement(LogoImage, { data: this.props.data.survey }));
}
renderPlaceHolder() {
return this.model.allowEdit && !this.model.isUploading ? attachKey2click(React.createElement("div", { className: "svc-logo-image-placeholder", onClick: () => this.model.chooseFile(this.model) },
React.createElement("svg", null,
React.createElement("use", { xlinkHref: "#icon-image-48x48" })))) : null;
}
renderInput() {
return React.createElement("input", { "aria-hidden": "true", type: "file", tabIndex: -1, accept: this.model.acceptedTypes, className: "svc-choose-file-input" });
}
renderLoadingIndicator() {
return React.createElement("div", { className: "svc-logo-image__loading" },
React.createElement(LoadingIndicatorComponent, null));
}
render() {
let content = null;
if (this.model.survey.locLogo.renderedHtml && !this.model.isUploading) {
content = this.renderImage();
}
else if (this.model.isUploading) {
content = this.renderLoadingIndicator();
}
else {
content = this.renderPlaceHolder();
}
return (React.createElement("div", { ref: this.rootRef, className: "svc-logo-image" },
this.renderInput(),
content));
}
}
ReactElementFactory.Instance.registerElement("svc-logo-image", (props) => {
return React.createElement(LogoImageComponent, props);
});
class SurveyQuestionLinkValue extends SurveyQuestionElementBase {
get question() {
return this.questionBase;
}
renderClear() {
const showClear = this.questionBase.showClear;
if (!this.questionBase.isReadOnly && showClear) {
return (React.createElement(ActionButton, { classes: this.question.linkClearButtonCssClasses, click: () => this.question.doClearClick(), text: editorLocalization.getString("pe.clear") }));
}
else {
return null;
}
}
renderElement() {
return (React.createElement(React.Fragment, null,
React.createElement(ActionButton, { classes: this.question.linkSetButtonCssClasses, click: () => this.question.doLinkClick(), selected: this.question.isSelected, disabled: !this.question.isClickable, text: this.question.linkValueText, title: this.question.tooltip, iconName: this.question.iconName }),
this.renderClear()));
}
}
ReactQuestionFactory.Instance.registerQuestion("linkvalue", (props) => {
return React.createElement(SurveyQuestionLinkValue, props);
});
class SurveyElementEmbeddedSurvey extends SurveyQuestionElementBase {
get embeddedSurvey() {
return (this.props.element || this.props.question);
}
get creator() {
return this.props.creator;
}
render() {
if (!this.embeddedSurvey)
return null;
const survey = this.embeddedSurvey.embeddedSurvey;
if (!survey || !survey.currentPage)
return null;
return React.createElement(SurveyPage, { survey: survey, page: survey.currentPage, css: survey.css, creator: this.creator });
}
}
ReactQuestionFactory.Instance.registerQuestion("embeddedsurvey", (props) => {
return React.createElement(SurveyElementEmbeddedSurvey, props);
});
class QuestionEditorContentComponent extends React.Component {
get survey() {
return this.props.survey;
}
createQuestionElement(question) {
return ReactQuestionFactory.Instance.createQuestion(!question.isDefaultRendering || question.isDefaultRendering()
? question.getTemplate()
: question.getComponentName(), {
question: question,
isDisplayMode: question.isInputReadOnly,
creator: this,
});
}
questionTitleLocation() {
return this.survey.questionTitleLocation;
}
questionErrorLocation() {
return this.survey.questionErrorLocation;
}
renderError(key, error, cssClasses) {
return null;
}
render() {
const question = this.survey.getAllQuestions()[0];
return (React.createElement("div", { style: this.props.style },
React.createElement(SurveyQuestion, { creator: this, element: question })));
}
}
ReactElementFactory.Instance.registerElement("svc-question-editor-content", (props) => {
return React.createElement(QuestionEditorContentComponent, props);
});
class ItemValueAdornerComponent extends CreatorModelElement {
constructor(props) {
super(props);
this.onBlur = (event) => {
this.model.onFocusOut(event.nativeEvent);
};
this.rootRef = React.createRef();
}
createModel(props) {
this.model = new ItemValueWrapperViewModel(props.componentData.creator, props.question, props.item);
}
getUpdatedModelProps() {
return ["question", "item"];
}
getStateElement() {
return this.model;
}
componentDidUpdate(prevProps, prevState) {
super.componentDidUpdate(prevProps, prevState);
this.props.item.setRootElement(this.rootRef.current);
if (prevProps.item !== this.props.item && prevProps.item) {
prevProps.item.setRootElement(undefined);
}
}
componentDidMount() {
super.componentDidMount();
this.props.item.setRootElement(this.rootRef.current);
}
componentWillUnmount() {
super.componentWillUnmount();
this.props.item.setRootElement(undefined);
}
render() {
this.model.item = this.props.item;
const button = this.model.allowAdd ? (attachKey2click(React.createElement("span", { role: "button", className: "svc-item-value-controls__button svc-item-value-controls__add", "aria-label": this.model.tooltip, onClick: () => {
this.model.add(this.model);
this.model.isNew = false;
} },
React.createElement(SvgIcon, { size: "auto", iconName: "icon-add_16x16", title: this.model.tooltip })))) : (React.createElement(React.Fragment, null,
" ",
this.model.isDraggable ? (React.createElement("span", { className: "svc-item-value-controls__button svc-item-value-controls__drag" },
React.createElement(SvgIcon, { className: "svc-item-value-controls__drag-icon", size: "auto", iconName: "icon-drag-24x24", title: this.model.dragTooltip }))) : null