UNPKG

survey-react-ui

Version:

survey.js is a JavaScript Survey Library. It is a modern way to add a survey to your website. It uses JSON for survey metadata and results.

1,095 lines (1,073 loc) 344 kB
/*! * surveyjs - Survey JavaScript library v2.3.14 * Copyright (c) 2015-2025 Devsoft Baltic OÜ - http://surveyjs.io/ * License: MIT (http://www.opensource.org/licenses/mit-license.php) */ import { SurveyModel, Helpers, createSvg, createPopupViewModel, CssClassBuilder, ActionDropdownViewModel, RendererFactory, doKey2ClickUp, SvgRegistry, settings, createPopupModalViewModel, ScrollViewModel, doKey2ClickBlur, doKey2ClickDown, addIconsToThemeSet, Question, SurveyProgressModel, ProgressButtonsResponsivityManager, PopupSurveyModel, ButtonGroupItemModel, LocalizableString, checkLibraryVersion } from 'survey-core'; export { SurveyModel as Model, SurveyModel, SurveyWindowModel, settings, surveyLocalization, surveyStrings } from 'survey-core'; import * as React from 'react'; import * as ReactDOM from 'react-dom'; import { createPortal } from 'react-dom'; class ReactElementFactory { constructor() { this.creatorHash = {}; } registerElement(elementType, elementCreator) { this.creatorHash[elementType] = elementCreator; } getAllTypes() { var result = new Array(); for (var key in this.creatorHash) { result.push(key); } return result.sort(); } isElementRegistered(elementType) { return !!this.creatorHash[elementType]; } createElement(elementType, params) { var creator = this.creatorHash[elementType]; if (creator == null) return null; return creator(params); } } ReactElementFactory.Instance = new ReactElementFactory(); class ReactSurveyElementsWrapper { static wrapRow(survey, element, row) { const componentName = survey.getRowWrapperComponentName(row); const componentData = survey.getRowWrapperComponentData(row); return ReactElementFactory.Instance.createElement(componentName, { element, row, componentData, }); } static wrapElement(survey, element, question) { const componentName = survey.getElementWrapperComponentName(question); const componentData = survey.getElementWrapperComponentData(question); return ReactElementFactory.Instance.createElement(componentName, { element, question, componentData, }); } static wrapQuestionContent(survey, element, question) { const componentName = survey.getQuestionContentWrapperComponentName(question); const componentData = survey.getElementWrapperComponentData(question); return ReactElementFactory.Instance.createElement(componentName, { element, question, componentData, }); } static wrapItemValue(survey, element, question, item) { const componentName = survey.getItemValueWrapperComponentName(item, question); const componentData = survey.getItemValueWrapperComponentData(item, question); return ReactElementFactory.Instance.createElement(componentName, { key: element === null || element === void 0 ? void 0 : element.key, element, question, item, componentData, }); } static wrapMatrixCell(survey, element, cell, reason = "cell") { const componentName = survey.getElementWrapperComponentName(cell, reason); const componentData = survey.getElementWrapperComponentData(cell, reason); return ReactElementFactory.Instance.createElement(componentName, { element, cell, componentData, }); } } SurveyModel.platform = "react"; class SurveyElementBase extends React.Component { static renderLocString(locStr, style = null, key) { return ReactElementFactory.Instance.createElement(locStr.renderAs, { locStr: locStr.renderAsData, style: style, key: key, }); } static renderQuestionDescription(question) { var descriptionText = SurveyElementBase.renderLocString(question.locDescription); return React.createElement("div", { style: question.hasDescription ? undefined : { display: "none" }, id: question.ariaDescriptionId, className: question.cssDescription }, descriptionText); } constructor(props) { super(props); this._allowComponentUpdate = true; this.prevStateElements = []; this.propertyValueChangedHandler = (stateElement, options) => { const key = options.name; if (!this.canUsePropInState(key) || this.isRendering) return; this.changedStatePropNameValue = key; this.setState((state) => { var newState = {}; newState[key] = options.newValue; return newState; }); }; this.onArrayChangedCallback = (stateElement, options) => { if (this.isRendering) return; this.changedStatePropNameValue = options.name; this.setState((state) => { var newState = {}; newState[options.name] = options.newValue; return newState; }); }; } componentDidMount() { this.makeBaseElementsReact(); } componentWillUnmount() { this.unMakeBaseElementsReact(); this.disableStateElementsRerenderEvent(this.getStateElements()); } componentDidUpdate(prevProps, prevState) { var _a; this.makeBaseElementsReact(); const stateElements = this.getStateElements(); this.disableStateElementsRerenderEvent(((_a = this.prevStateElements) !== null && _a !== void 0 ? _a : []).filter(el => !stateElements.find(stateElement => stateElement == el))); this.prevStateElements = []; this.getStateElements().forEach((el) => { el.afterRerender(); }); } allowComponentUpdate() { this._allowComponentUpdate = true; this.forceUpdate(); } denyComponentUpdate() { this._allowComponentUpdate = false; } shouldComponentUpdate(nextProps, nextState) { if (this._allowComponentUpdate) { this.unMakeBaseElementsReact(); this.prevStateElements = this.getStateElements(); } return this._allowComponentUpdate; } render() { if (!this.canRender()) { return null; } this.startEndRendering(1); var res = this.renderElement(); this.startEndRendering(-1); if (!!res) { res = this.wrapElement(res); } this.changedStatePropNameValue = undefined; return res; } wrapElement(element) { return element; } get isRendering() { var stateEls = this.getRenderedElements(); for (let stateEl of stateEls) { if (stateEl.reactRendering > 0) return true; } return false; } getRenderedElements() { return this.getStateElements(); } startEndRendering(val) { var stateEls = this.getRenderedElements(); for (let stateEl of stateEls) { if (!stateEl.reactRendering) stateEl.reactRendering = 0; stateEl.reactRendering += val; } } canRender() { return true; } renderElement() { return null; } get changedStatePropName() { return this.changedStatePropNameValue; } makeBaseElementsReact() { var els = this.getStateElements(); for (var i = 0; i < els.length; i++) { els[i].enableOnElementRerenderedEvent(); this.makeBaseElementReact(els[i]); } } unMakeBaseElementsReact() { var els = this.getStateElements(); this.unMakeBaseElementsReactive(els); } unMakeBaseElementsReactive(els) { for (var i = 0; i < els.length; i++) { this.unMakeBaseElementReact(els[i]); } } disableStateElementsRerenderEvent(els) { els.forEach(el => { el.disableOnElementRerenderedEvent(); }); } getStateElements() { var el = this.getStateElement(); return !!el ? [el] : []; } getStateElement() { return null; } get isDisplayMode() { const props = this.props; return props.isDisplayMode || false; } renderLocString(locStr, style = null, key) { return SurveyElementBase.renderLocString(locStr, style, key); } canMakeReact(stateElement) { return !!stateElement && !!stateElement.iteratePropertiesHash; } makeBaseElementReact(stateElement) { if (!this.canMakeReact(stateElement)) return; stateElement.addOnArrayChangedCallback(this.onArrayChangedCallback); stateElement.addOnPropertyValueChangedCallback(this.propertyValueChangedHandler); } canUsePropInState(key) { return true; } unMakeBaseElementReact(stateElement) { if (!this.canMakeReact(stateElement)) return; stateElement.removeOnPropertyValueChangedCallback(this.propertyValueChangedHandler); stateElement.removeOnArrayChangedCallback(this.onArrayChangedCallback); } } class ReactSurveyElement extends SurveyElementBase { constructor(props) { super(props); } get cssClasses() { return this.props.cssClasses; } } class SurveyQuestionElementBase extends SurveyElementBase { constructor(props) { super(props); } componentDidUpdate(prevProps, prevState) { super.componentDidUpdate(prevProps, prevState); this.updateDomElement(); } componentDidMount() { super.componentDidMount(); this.updateDomElement(); } componentWillUnmount() { super.componentWillUnmount(); if (!!this.questionBase) { const contentElement = this.content || this.control; this.questionBase.beforeDestroyQuestionElement(contentElement); if (!!contentElement) { contentElement.removeAttribute("data-rendered"); } } } updateDomElement() { const contentElement = this.content || this.control; if (!!contentElement) { if (contentElement.getAttribute("data-rendered") !== "r") { contentElement.setAttribute("data-rendered", "r"); this.questionBase.afterRenderQuestionElement(contentElement); } } } get questionBase() { return this.props.question; } getRenderedElements() { return [this.questionBase]; } get creator() { return this.props.creator; } canRender() { return !!this.questionBase && !!this.creator; } shouldComponentUpdate(nextProps, nextState) { if (!super.shouldComponentUpdate(nextProps, nextState)) return false; return (!this.questionBase.customWidget || !!this.questionBase.customWidgetData.isNeedRender || !!this.questionBase.customWidget.widgetJson.isDefaultRender || !!this.questionBase.customWidget.widgetJson.render); } get isDisplayMode() { const props = this.props; return (props.isDisplayMode || (!!this.questionBase && this.questionBase.isInputReadOnly) || false); } wrapCell(cell, element, reason) { if (!reason) { return element; } const survey = this.questionBase .survey; let wrapper = null; if (survey) { wrapper = ReactSurveyElementsWrapper.wrapMatrixCell(survey, element, cell, reason); } return wrapper !== null && wrapper !== void 0 ? wrapper : element; } setControl(element) { if (!!element) { this.control = element; } } setContent(element) { if (!!element) { this.content = element; } } } class SurveyQuestionUncontrolledElement extends SurveyQuestionElementBase { constructor(props) { super(props); this.updateValueOnEvent = (event) => { if (!Helpers.isTwoValueEquals(this.questionBase.value, event.target.value, false, true, false)) { this.setValueCore(event.target.value); } }; this.updateValueOnEvent = this.updateValueOnEvent.bind(this); } get question() { return this.questionBase; } setValueCore(newValue) { this.questionBase.value = newValue; } getValueCore() { return this.questionBase.value; } updateDomElement() { if (!!this.control) { const control = this.control; const newValue = this.getValueCore(); if (!Helpers.isTwoValueEquals(newValue, control.value, false, true, false)) { control.value = this.getValue(newValue); } } super.updateDomElement(); } getValue(val) { if (Helpers.isValueEmpty(val)) return ""; return val; } } class SvgIcon extends React.Component { constructor(props) { super(props); this.svgIconRef = React.createRef(); } updateSvg() { if (this.props.iconName) createSvg(this.props.size, this.props.width, this.props.height, this.props.iconName, this.svgIconRef.current, this.props.title); } componentDidUpdate() { this.updateSvg(); } render() { let className = "sv-svg-icon"; if (this.props.className) { className += " " + this.props.className; } return (this.props.iconName ? React.createElement("svg", { className: className, style: this.props.style, onClick: this.props.onClick, ref: this.svgIconRef, role: "presentation" }, React.createElement("use", null)) : null); } componentDidMount() { this.updateSvg(); } } ReactElementFactory.Instance.registerElement("sv-svg-icon", (props) => { return React.createElement(SvgIcon, props); }); class SurveyActionBarSeparator extends React.Component { constructor(props) { super(props); } render() { var className = `sv-action-bar-separator ${this.props.cssClasses}`; return React.createElement("div", { className: className }); } } ReactElementFactory.Instance.registerElement("sv-action-bar-separator", (props) => { return React.createElement(SurveyActionBarSeparator, props); }); class SurveyAction extends SurveyElementBase { constructor(props) { super(props); this.ref = React.createRef(); } get item() { return this.props.item; } getStateElement() { return this.item; } renderElement() { //refactor const itemClass = this.item.getActionRootCss(); const separator = this.item.needSeparator ? (React.createElement(SurveyActionBarSeparator, null)) : null; const itemComponent = ReactElementFactory.Instance.createElement(this.item.component || "sv-action-bar-item", { item: this.item, }); return (React.createElement("div", { className: itemClass, id: this.item.id, ref: this.ref }, React.createElement("div", { className: "sv-action__content" }, separator, itemComponent))); } componentWillUnmount() { super.componentWillUnmount(); this.item.updateModeCallback = undefined; } 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(); } } class SurveyActionBarItem extends SurveyElementBase { get item() { return this.props.item; } getStateElement() { return this.item; } renderElement() { return React.createElement(React.Fragment, null, this.renderInnerButton()); } renderText() { if (!this.item.hasTitle) return null; const titleClass = this.item.getActionBarItemTitleCss(); return React.createElement("span", { className: titleClass }, this.item.title); } renderButtonContent() { const text = this.renderText(); const svgIcon = !!this.item.iconName ? (React.createElement(SvgIcon, { className: this.item.cssClasses.itemIcon, size: this.item.iconSize, iconName: this.item.iconName, title: this.item.tooltip || this.item.title })) : null; return (React.createElement(React.Fragment, null, svgIcon, text)); } renderInnerButton() { const className = this.item.getActionBarItemCss(); const title = this.item.tooltip || this.item.title; const buttonContent = this.renderButtonContent(); const tabIndex = this.item.disableTabStop ? -1 : undefined; const button = attachKey2click(React.createElement("button", { className: className, type: "button", disabled: this.item.disabled, onMouseDown: (args) => this.item.doMouseDown(args), onFocus: (args) => this.item.doFocus(args), onClick: (args) => this.item.doAction(args), title: title, tabIndex: tabIndex, "aria-checked": this.item.ariaChecked, "aria-expanded": this.item.ariaExpanded, role: this.item.ariaRole }, buttonContent), this.item, { processEsc: false }); return button; } } ReactElementFactory.Instance.registerElement("sv-action-bar-item", (props) => { return React.createElement(SurveyActionBarItem, props); }); class Popup extends SurveyElementBase { constructor(props) { super(props); this.containerRef = React.createRef(); this.createModel(); } get model() { return this.props.model; } getStateElement() { return this.model; } createModel() { this.popup = createPopupViewModel(this.props.model); } setTargetElement() { const container = this.containerRef.current; this.popup.setComponentElement(container); } componentDidMount() { super.componentDidMount(); this.setTargetElement(); } componentDidUpdate(prevProps, prevState) { super.componentDidUpdate(prevProps, prevState); this.setTargetElement(); } componentWillUnmount() { super.componentWillUnmount(); this.popup.resetComponentElement(); } shouldComponentUpdate(nextProps, nextState) { var _a; if (!super.shouldComponentUpdate(nextProps, nextState)) return false; const isNeedUpdate = nextProps.model !== this.popup.model; if (isNeedUpdate) { (_a = this.popup) === null || _a === void 0 ? void 0 : _a.dispose(); this.createModel(); } return isNeedUpdate; } render() { this.popup.model = this.model; let popupContainer; if (this.model.isModal) { popupContainer = React.createElement(PopupContainer, { model: this.popup }); } else { popupContainer = React.createElement(PopupDropdownContainer, { model: this.popup }); } return React.createElement("div", { ref: this.containerRef }, popupContainer); } } ReactElementFactory.Instance.registerElement("sv-popup", (props) => { return React.createElement(Popup, props); }); class PopupContainer extends SurveyElementBase { constructor(props) { super(props); this.handleKeydown = (event) => { this.model.onKeyDown(event); }; this.clickInside = (ev) => { ev.stopPropagation(); }; } get model() { return this.props.model; } getStateElement() { return this.model; } componentDidUpdate(prevProps, prevState) { super.componentDidUpdate(prevProps, prevState); if (!this.model.isPositionSet && this.model.isVisible) { this.model.updateOnShowing(); } } renderContainer(popupBaseViewModel) { const headerPopup = popupBaseViewModel.showHeader ? this.renderHeaderPopup(popupBaseViewModel) : null; const headerContent = !!popupBaseViewModel.title ? this.renderHeaderContent() : null; const content = this.renderContent(); const footerContent = popupBaseViewModel.showFooter ? this.renderFooter(this.model) : null; return (React.createElement("div", { className: "sv-popup__container", style: { left: popupBaseViewModel.left, top: popupBaseViewModel.top, height: popupBaseViewModel.height, width: popupBaseViewModel.width, minWidth: popupBaseViewModel.minWidth, }, onClick: (ev) => { this.clickInside(ev); } }, headerPopup, React.createElement("div", { className: "sv-popup__body-content" }, headerContent, React.createElement("div", { className: "sv-popup__scrolling-content" }, content), footerContent))); } renderHeaderContent() { return React.createElement("div", { className: "sv-popup__body-header" }, this.model.title); } renderContent() { const contentComponent = ReactElementFactory.Instance.createElement(this.model.contentComponentName, this.model.contentComponentData); return React.createElement("div", { className: "sv-popup__content" }, contentComponent); } renderHeaderPopup(popupModel) { return null; } renderFooter(popuModel) { return (React.createElement("div", { className: "sv-popup__body-footer" }, React.createElement(SurveyActionBar, { model: popuModel.footerToolbar }))); } render() { const container = this.renderContainer(this.model); const className = new CssClassBuilder() .append("sv-popup") .append(this.model.styleClass) .toString(); const style = { display: this.model.isVisible ? "" : "none", }; return (React.createElement("div", { tabIndex: -1, className: className, style: style, onClick: (e) => { this.model.clickOutside(e); }, onBlur: (e) => { this.model.blur(e); }, onKeyDown: this.handleKeydown }, container)); } componentDidMount() { super.componentDidMount(); if (this.model.isVisible) { this.model.updateOnShowing(); } } } class PopupDropdownContainer extends PopupContainer { renderHeaderPopup(popupModel) { const popupDropdownModel = popupModel; if (!popupDropdownModel) return null; return (React.createElement("span", { style: { left: popupDropdownModel.pointerTarget.left, top: popupDropdownModel.pointerTarget.top, }, className: "sv-popup__pointer" })); } } class SurveyActionBarItemDropdown extends SurveyActionBarItem { constructor(props) { super(props); } renderInnerButton() { const button = super.renderInnerButton(); return (React.createElement(React.Fragment, null, button, React.createElement(Popup, { model: this.item.popupModel }))); } componentDidMount() { this.viewModel = new ActionDropdownViewModel(this.item); } componentWillUnmount() { super.componentWillUnmount(); this.viewModel.dispose(); } } ReactElementFactory.Instance.registerElement("sv-action-bar-item-dropdown", (props) => { return React.createElement(SurveyActionBarItemDropdown, props); }); class SurveyActionBar extends SurveyElementBase { constructor(props) { super(props); this.rootRef = React.createRef(); } get handleClick() { return this.props.handleClick !== undefined ? this.props.handleClick : true; } get model() { return this.props.model; } componentDidMount() { super.componentDidMount(); if (!this.model.hasVisibleActions) return; const container = this.rootRef.current; if (!!container) { this.model.initResponsivityManager(container, (callback) => { setTimeout(callback, 100); }); } } componentWillUnmount() { super.componentWillUnmount(); this.model.resetResponsivityManager(); } componentDidUpdate(prevProps, prevState) { super.componentDidUpdate(prevProps, prevState); if (prevProps.model != this.props.model) { prevProps.model.resetResponsivityManager(); } if (!!this.model.hasVisibleActions) { const container = this.rootRef.current; if (!!container) { this.model.initResponsivityManager(container, (callback) => { setTimeout(callback, 100); }); } } } getStateElement() { return this.model; } renderElement() { if (!this.model.hasActions) return null; const items = this.renderItems(); return (React.createElement("div", { ref: this.rootRef, style: this.model.getRootStyle(), className: this.model.getRootCss(), onClick: this.handleClick ? function (event) { event.stopPropagation(); } : undefined }, items)); } renderItems() { return this.model.renderedActions.concat([]).map((item, itemIndex) => { return (React.createElement(SurveyAction, { item: item, key: item.renderedId })); }); } } ReactElementFactory.Instance.registerElement("sv-action-bar", (props) => { return React.createElement(SurveyActionBar, props); }); class TitleContent extends React.Component { constructor(props) { super(props); } get cssClasses() { return this.props.cssClasses; } get element() { return this.props.element; } render() { if (this.element.isTitleRenderedAsString) return SurveyElementBase.renderLocString(this.element.locRenderedTitle); var spans = this.renderTitleSpans(this.element.getTitleOwner(), this.cssClasses); return React.createElement(React.Fragment, null, spans); } renderTitleSpans(element, cssClasses) { var getSpaceSpan = (key) => { return (React.createElement("span", { "data-key": key, key: key }, "\u00A0")); }; var spans = []; if (element.isRequireTextOnStart) { spans.push(this.renderRequireText(element)); spans.push(getSpaceSpan("req-sp")); } var questionNumber = element.no; if (questionNumber) { spans.push(React.createElement("span", { "data-key": "q_num", key: "q_num", className: element.cssTitleNumber, style: { position: "static" }, "aria-hidden": true }, questionNumber)); spans.push(getSpaceSpan("num-sp")); } if (element.isRequireTextBeforeTitle) { spans.push(this.renderRequireText(element)); spans.push(getSpaceSpan("req-sp")); } spans.push(SurveyElementBase.renderLocString(element.locRenderedTitle, null, "q_title")); if (element.isRequireTextAfterTitle) { spans.push(getSpaceSpan("req-sp")); spans.push(this.renderRequireText(element)); } return spans; } renderRequireText(element) { return (React.createElement("span", { "data-key": "req-text", key: "req-text", className: element.cssRequiredMark, "aria-hidden": true }, element.requiredMark)); } } class TitleActions extends React.Component { get cssClasses() { return this.props.cssClasses; } get element() { return this.props.element; } get renderActions() { return this.props.renderActions === undefined ? true : this.props.renderActions; } render() { const titleContent = React.createElement(TitleContent, { element: this.element, cssClasses: this.cssClasses }); if (!this.element.hasTitleActions) return titleContent; return (React.createElement("div", { className: "sv-title-actions" }, React.createElement("span", { className: "sv-title-actions__title" }, titleContent), (this.renderActions ? React.createElement(SurveyActionBar, { model: this.element.getTitleToolbar() }) : null))); } } RendererFactory.Instance.registerRenderer("element", "title-actions", "sv-title-actions"); ReactElementFactory.Instance.registerElement("sv-title-actions", (props) => { return React.createElement(TitleActions, props); }); class TitleElement extends React.Component { constructor(props) { super(props); } get element() { return this.props.element; } renderTitleExpandableSvg() { if (!this.element.getCssTitleExpandableSvg()) return null; let iconName = this.element.isExpanded ? "icon-collapse-16x16" : "icon-expand-16x16"; return React.createElement(SvgIcon, { className: this.element.getCssTitleExpandableSvg(), iconName: iconName, size: "auto" }); } render() { const element = this.element; if (!element || !element.hasTitle) return null; const ariaLabel = element.titleAriaLabel || undefined; const titleExpandableSvg = this.renderTitleExpandableSvg(); const titleContent = (React.createElement(TitleActions, { element: element, cssClasses: element.cssClasses, renderActions: this.props.renderActions })); let onClick = undefined; let onKeyUp = undefined; if (element.hasTitleEvents) { onKeyUp = (evt) => { doKey2ClickUp(evt.nativeEvent); }; } const CustomTag = element.titleTagName; return (React.createElement(CustomTag, { className: element.cssTitle, id: element.ariaTitleId, "aria-label": ariaLabel, tabIndex: element.titleTabIndex, "aria-expanded": element.titleAriaExpanded, role: element.titleAriaRole, onClick: onClick, onKeyUp: onKeyUp }, titleExpandableSvg, titleContent)); } } class SurveyHeader extends React.Component { constructor(props) { super(props); this.state = { changed: 0 }; this.rootRef = React.createRef(); } get survey() { return this.props.survey; } get css() { return this.survey.css; } componentDidMount() { const self = this; this.survey.afterRenderHeader(this.rootRef.current); this.survey.locLogo.onChanged = function () { self.setState({ changed: self.state.changed + 1 }); }; } componentWillUnmount() { this.survey.locLogo.onChanged = function () { }; } renderTitle() { if (!this.survey.renderedHasTitle) return null; const description = SurveyElementBase.renderLocString(this.survey.locDescription); return (React.createElement("div", { className: this.css.headerText, style: { maxWidth: this.survey.titleMaxWidth } }, React.createElement(TitleElement, { element: this.survey }), this.survey.renderedHasDescription ? React.createElement("div", { className: this.css.description }, description) : null)); } renderLogoImage(isRender) { if (!isRender) return null; const componentName = this.survey.getElementWrapperComponentName(this.survey, "logo-image"); const componentData = this.survey.getElementWrapperComponentData(this.survey, "logo-image"); return ReactElementFactory.Instance.createElement(componentName, { data: componentData, }); } render() { if (!this.survey.renderedHasHeader) return null; return (React.createElement("div", { className: this.css.header, ref: this.rootRef }, this.renderLogoImage(this.survey.isLogoBefore), this.renderTitle(), this.renderLogoImage(this.survey.isLogoAfter), React.createElement("div", { className: this.css.headerClose }))); } } ReactElementFactory.Instance.registerElement("survey-header", (props) => { return React.createElement(SurveyHeader, props); }); class ReactQuestionFactory { constructor() { this.creatorHash = {}; } registerQuestion(questionType, questionCreator) { this.creatorHash[questionType] = questionCreator; } getAllTypes() { var result = new Array(); for (var key in this.creatorHash) { result.push(key); } return result.sort(); } createQuestion(questionType, params) { var creator = this.creatorHash[questionType]; if (creator == null) return null; return creator(params); } } ReactQuestionFactory.Instance = new ReactQuestionFactory(); class BrandInfo extends React.Component { render() { return (React.createElement("div", { className: "sv-brand-info" }, React.createElement("a", { className: "sv-brand-info__logo", href: "https://surveyjs.io/?utm_source=built-in_links&utm_medium=online_survey_tool&utm_campaign=landing_page" }, React.createElement("img", { src: "https://surveyjs.io/Content/Images/poweredby.svg" })), React.createElement("div", { className: "sv-brand-info__text" }, "Try and see how easy it is to ", React.createElement("a", { href: "https://surveyjs.io/create-survey?utm_source=built-in_links&utm_medium=online_survey_tool&utm_campaign=create_survey" }, "create a survey")), React.createElement("div", { className: "sv-brand-info__terms" }, React.createElement("a", { href: "https://surveyjs.io/TermsOfUse" }, "Terms of Use & Privacy Statement")))); } } class NotifierComponent extends SurveyElementBase { get notifier() { return this.props.notifier; } getStateElement() { return this.notifier; } renderElement() { if (!this.notifier.isDisplayed) return null; const style = { visibility: this.notifier.active ? "visible" : "hidden" }; return (React.createElement("div", { className: this.notifier.css, style: style, role: "alert", "aria-live": "polite" }, React.createElement("span", null, this.notifier.message), React.createElement(SurveyActionBar, { model: this.notifier.actionBar }))); } } ReactElementFactory.Instance.registerElement("sv-notifier", (props) => { return React.createElement(NotifierComponent, props); }); class ComponentsContainer extends React.Component { render() { const components = this.props.survey.getContainerContent(this.props.container); const needRenderWrapper = this.props.needRenderWrapper === false ? false : true; if (components.length == 0) { return null; } if (!needRenderWrapper) { return React.createElement(React.Fragment, null, components.map(component => { return ReactElementFactory.Instance.createElement(component.component, { survey: this.props.survey, model: component.data, container: this.props.container, key: component.id }); })); } return React.createElement("div", { className: "sv-components-column" + " sv-components-container-" + this.props.container }, components.map(component => { return ReactElementFactory.Instance.createElement(component.component, { survey: this.props.survey, model: component.data, container: this.props.container, key: component.id }); })); } } ReactElementFactory.Instance.registerElement("sv-components-container", (props) => { return React.createElement(ComponentsContainer, props); }); class SvgBundleComponent extends React.Component { constructor(props) { super(props); this.onIconsChanged = () => { if (!!this.containerRef.current) { this.containerRef.current.innerHTML = SvgRegistry.iconsRenderedHtml(); } }; this.containerRef = React.createRef(); } componentDidMount() { this.onIconsChanged(); SvgRegistry.onIconsChanged.add(this.onIconsChanged); } componentWillUnmount() { SvgRegistry.onIconsChanged.remove(this.onIconsChanged); } render() { const svgStyle = { display: "none" }; return React.createElement("svg", { style: svgStyle, id: "sv-icon-holder-global-container", ref: this.containerRef }); } } class PopupModal extends SurveyElementBase { constructor(props) { super(props); this.isInitialized = false; this.init = () => { if (!this.isInitialized) { settings.showDialog = (dialogOptions, rootElement) => { return this.showDialog(dialogOptions, rootElement); }; this.isInitialized = true; } }; this.clean = () => { if (this.isInitialized) { settings.showDialog = undefined; this.isInitialized = false; } }; this.state = { changed: 0 }; this.descriptor = { init: this.init, clean: this.clean }; } static addModalDescriptor(descriptor) { if (!settings.showDialog) { descriptor.init(); } this.modalDescriptors.push(descriptor); } static removeModalDescriptor(descriptor) { descriptor.clean(); this.modalDescriptors.splice(this.modalDescriptors.indexOf(descriptor), 1); if (!settings.showDialog && this.modalDescriptors[0]) { this.modalDescriptors[0].init(); } } renderElement() { if (!this.model) return null; return createPortal(React.createElement(PopupContainer, { model: this.model }), this.model.container); } showDialog(dialogOptions, rootElement) { this.model = createPopupModalViewModel(dialogOptions, rootElement); const onVisibilityChangedCallback = (_, options) => { if (!options.isVisible) { this.model.dispose(); this.model = undefined; this.setState({ changed: this.state.changed + 1 }); } }; this.model.onVisibilityChanged.add(onVisibilityChangedCallback); this.model.model.isVisible = true; this.setState({ changed: this.state.changed + 1 }); return this.model; } componentDidMount() { PopupModal.addModalDescriptor(this.descriptor); } componentWillUnmount() { if (this.model) { this.model.dispose(); this.model = undefined; } PopupModal.removeModalDescriptor(this.descriptor); } } PopupModal.modalDescriptors = []; /*! * surveyjs - Survey JavaScript library v2.3.14 * Copyright (c) 2015-2025 Devsoft Baltic OÜ - http://surveyjs.io/ * License: MIT (http://www.opensource.org/licenses/mit-license.php) */ var iconsV1 = { "modernbooleancheckchecked": "<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 24 24\"><polygon points=\"19,10 14,10 14,5 10,5 10,10 5,10 5,14 10,14 10,19 14,19 14,14 19,14 \"></polygon></svg>", "modernbooleancheckind": "<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 24 24\"><path d=\"M22,0H2C0.9,0,0,0.9,0,2v20c0,1.1,0.9,2,2,2h20c1.1,0,2-0.9,2-2V2C24,0.9,23.1,0,22,0z M21,18L6,3h15V18z M3,6l15,15H3V6z\"></path></svg>", "modernbooleancheckunchecked": "<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 24 24\"><rect x=\"5\" y=\"10\" width=\"14\" height=\"4\"></rect></svg>", "moderncheck": "<svg viewBox=\"0 0 24 24\"><path d=\"M5,13l2-2l3,3l7-7l2,2l-9,9L5,13z\"></path></svg>", "modernradio": "<svg viewBox=\"-12 -12 24 24\"><circle r=\"6\" cx=\"0\" cy=\"0\"></circle></svg>", "progressbutton": "<svg viewBox=\"0 0 10 10\"><polygon points=\"2,2 0,4 5,9 10,4 8,2 5,5 \"></polygon></svg>", "removefile": "<svg viewBox=\"0 0 16 16\"><path d=\"M8,2C4.7,2,2,4.7,2,8s2.7,6,6,6s6-2.7,6-6S11.3,2,8,2z M11,10l-1,1L8,9l-2,2l-1-1l2-2L5,6l1-1l2,2l2-2l1,1L9,8 L11,10z\"></path></svg>", "timercircle": "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 160 160\"><circle cx=\"80\" cy=\"80\" r=\"70\" style=\"stroke: var(--sd-timer-stroke-background-color); stroke-width: var(--sd-timer-stroke-background-width)\" stroke-dasharray=\"none\" stroke-dashoffset=\"none\"></circle><circle cx=\"80\" cy=\"80\" r=\"70\"></circle></svg>", "add-24x24": "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M13 11H17V13H13V17H11V13H7V11H11V7H13V11ZM23 12C23 18.1 18.1 23 12 23C5.9 23 1 18.1 1 12C1 5.9 5.9 1 12 1C18.1 1 23 5.9 23 12ZM21 12C21 7 17 3 12 3C7 3 3 7 3 12C3 17 7 21 12 21C17 21 21 17 21 12Z\"></path></svg>", "arrowleft-16x16": "<svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M15 8.99999H4.4L8.7 13.3L7.3 14.7L0.599998 7.99999L7.3 1.29999L8.7 2.69999L4.4 6.99999H15V8.99999Z\"></path></svg>", "arrowright-16x16": "<svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M1 6.99999H11.6L7.3 2.69999L8.7 1.29999L15.4 7.99999L8.7 14.7L7.3 13.3L11.6 8.99999H1V6.99999Z\"></path></svg>", "camera-24x24": "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M20.01 4H18.4C18.2 4 18.01 3.9 17.9 3.73L16.97 2.34C16.41 1.5 15.48 1 14.47 1H9.54C8.53 1 7.6 1.5 7.04 2.34L6.11 3.73C6 3.9 5.81 4 5.61 4H4C2.35 4 1 5.35 1 7V19C1 20.65 2.35 22 4 22H20C21.65 22 23 20.65 23 19V7C23 5.35 21.65 4 20 4H20.01ZM21.01 19C21.01 19.55 20.56 20 20.01 20H4.01C3.46 20 3.01 19.55 3.01 19V7C3.01 6.45 3.46 6 4.01 6H5.62C6.49 6 7.3 5.56 7.79 4.84L8.72 3.45C8.91 3.17 9.22 3 9.55 3H14.48C14.81 3 15.13 3.17 15.31 3.45L16.24 4.84C16.72 5.56 17.54 6 18.41 6H20.02C20.57 6 21.02 6.45 21.02 7V19H21.01ZM12.01 6C8.7 6 6.01 8.69 6.01 12C6.01 15.31 8.7 18 12.01 18C15.32 18 18.01 15.31 18.01 12C18.01 8.69 15.32 6 12.01 6ZM12.01 16C9.8 16 8.01 14.21 8.01 12C8.01 9.79 9.8 8 12.01 8C14.22 8 16.01 9.79 16.01 12C16.01 14.21 14.22 16 12.01 16ZM13.01 10C13.01 10.55 12.56 11 12.01 11C11.46 11 11.01 11.45 11.01 12C11.01 12.55 10.56 13 10.01 13C9.46 13 9.01 12.55 9.01 12C9.01 10.35 10.36 9 12.01 9C12.56 9 13.01 9.45 13.01 10Z\"></path></svg>", "camera-32x32": "<svg viewBox=\"0 0 32 32\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M27 6H23.8C23.34 6 22.92 5.77 22.66 5.39L22.25 4.78C21.51 3.66 20.26 3 18.92 3H13.06C11.72 3 10.48 3.67 9.73 4.78L9.32 5.39C9.07 5.77 8.64 6 8.18 6H4.98C2.79 6 1 7.79 1 10V24C1 26.21 2.79 28 5 28H27C29.21 28 31 26.21 31 24V10C31 7.79 29.21 6 27 6ZM29 24C29 25.1 28.1 26 27 26H5C3.9 26 3 25.1 3 24V10C3 8.9 3.9 8 5 8H8.2C9.33 8 10.38 7.44 11 6.5L11.41 5.89C11.78 5.33 12.41 5 13.07 5H18.93C19.6 5 20.22 5.33 20.59 5.89L21 6.5C21.62 7.44 22.68 8 23.8 8H27C28.1 8 29 8.9 29 10V24ZM16 9C12.13 9 9 12.13 9 16C9 19.87 12.13 23 16 23C19.87 23 23 19.87 23 16C23 12.13 19.87 9 16 9ZM16 21C13.24 21 11 18.76 11 16C11 13.24 13.24 11 16 11C18.76 11 21 13.24 21 16C21 18.76 18.76 21 16 21ZM17 13C17 13.55 16.55 14 16 14C14.9 14 14 14.9 14 16C14 16.55 13.55 17 13 17C12.45 17 12 16.55 12 16C12 13.79 13.79 12 16 12C16.55 12 17 12.45 17 13Z\"></path></svg>", "cancel-24x24": "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M22.6 8.6L16.4 2.4C16 2 15.5 1.8 15 1.8C14.5 1.8 14 2 13.6 2.4L1.40005 14.6C0.600049 15.4 0.600049 16.6 1.40005 17.4L6.00005 22H12L22.6 11.4C23.3 10.6 23.3 9.3 22.6 8.6ZM11.1 20H6.80005L2.80005 16L6.20005 12.6L12.4 18.8L11.1 20ZM13.8 17.4L7.60005 11.2L15 3.8L21.2 10L13.8 17.4ZM16 20H23V22H14L16 20Z\"></path></svg>", "check-16x16": "<svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M5.003 14.413L0.292999 9.70303L1.703 8.29303L5.003 11.583L14.293 2.29303L15.703 3.70303L5.003 14.413Z\"></path></svg>", "check-24x24": "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M9 20.1L1 12L3.1 9.9L9 15.9L20.9 4L23 6.1L9 20.1Z\"></path></svg>", "chevrondown-24x24": "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M12 15L17 10H7L12 15Z\"></path></svg>", "chevronright-16x16": "<svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M5.64648 12.6465L6.34648 13.3465L11.7465 8.04648L6.34648 2.64648L5.64648 3.34648L10.2465 8.04648L5.64648 12.6465Z\"></path></svg>", "clear-16x16": "<svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M13.35 3.34999L12.65 2.64999L8.05002 7.24999L3.35002 2.64999L2.65002 3.34999L7.25002 8.04999L2.65002 12.65L3.35002 13.35L8.05002 8.74999L12.65 13.35L13.35 12.65L8.75002 8.04999L13.35 3.34999Z\"></path></svg>", "clear-24x24": "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M22.6 8.6L16.4 2.4C16 2 15.5 1.8 15 1.8C14.5 1.8 14 2 13.6 2.4L1.40005 14.6C0.600049 15.4 0.600049 16.6 1.40005 17.4L6.00005 22H12L22.6 11.4C23.3 10.6 23.3 9.3 22.6 8.6ZM11.1 20H6.80005L2.80005 16L6.20005 12.6L12.4 18.8L11.1 20ZM13.8 17.4L7.60005 11.2L15 3.8L21.2 10L13.8 17.4ZM16 20H23V22H14L16 20Z\"></path></svg>", "close-16x16": "<svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M9.43 8.0025L13.7 3.7225C14.09 3.3325 14.09 2.6925 13.7 2.2925C13.31 1.9025 12.67 1.9025 12.27 2.2925L7.99 6.5725L3.72 2.3025C3.33 1.9025 2.69 1.9025 2.3 2.3025C1.9 2.6925 1.9 3.3325 2.3 3.7225L6.58 8.0025L2.3 12.2825C1.91 12.6725 1.91 13.3125 2.3 13.7125C2.69 14.1025 3.33 14.1025 3.73 13.7125L8.01 9.4325L12.29 13.7125C12.68 14.1025 13.32 14.1025 13.72 13.7125C14.11 13.3225 14.11 12.6825 13.72 12.2825L9.44 8.0025H9.43Z\"></path></svg>", "close-24x24": "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M13.4101 12L20.7001 4.71C21.0901 4.32 21.0901 3.69 20.7001 3.3C20.3101 2.91 19.6801 2.91 19.2901 3.3L12.0001 10.59L4.71006 3.29C4.32006 2.9 3.68006 2.9 3.29006 3.29C2.90006 3.68 2.90006 4.32 3.29006 4.71L10.5801 12L3.29006 19.29C2.90006 19.68 2.90006 20.31 3.29006 20.7C3.49006 20.9 3.74006 20.99 4.00006 20.99C4.26006 20.99 4.51006 20.89 4.71006 20.7L12.0001 13.41L19.2901 20.7C19.4901 20.9 19.7401 20.99 20.0001 20.99C20.2601 20.99 20.5101 20.89 20.7101 20.7C21.1001 20.31 21.1001 19.68 20.7101 19.29L13.4201 12H13.4101Z\"></path></svg>", "collapse-16x16": "<svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M2 6L3 5L8 10L13 5L14 6L8 12L2 6Z\"></path></svg>", "collapsedetails-16x16": "<svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M13 7H3V9H13V7Z\"></path></svg>", "delete-16x16": "<svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M15 2H14H11V1C11 0.4 10.6 0 10 0H7C6.4 0 6 0.4 6 1V2H3H2V4H3V14C3 15.1 3.9 16 5 16H12C13.1 16 14 15.1 14 14V4H15V2ZM7 1H10V2H7V1ZM12 14H5V4H12V14ZM7 13H6V5H7V13ZM9 13H8V5H9V13ZM11 13H10V5H11V13Z\"></path></svg>", "delete-24x24": "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M22 4H20H16V2C16 0.9 15.1 0 14 0H10C8.9 0 8 0.9 8 2V4H4H2V6H4V20C4 21.1 4.9 22 6 22H18C19.1 22 20 21.1 20 20V6H22V4ZM10 2H14V4H10V2ZM18 20H6V6H8H16H18V20ZM14 8H16V18H14V8ZM11 8H13V18H11V8ZM8 8H10V18H8V8Z\"></path></svg>", "drag-24x24": "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M13 6C13 4.9 13.9 4 15 4C16.1 4 17 4.9 17 6C17 7.1 16.1 8 15 8C13.9 8 13 7.1 13 6ZM9 4C7.9 4 7 4.9 7 6C7 7.1 7.9 8 9 8C10.1 8 11 7.1 11 6C11 4.9 10.1 4 9 4ZM15 10C13.9 10 13 10.9 13 12C13 13.1 13.9 14 15 14C16.1 14 17 13.1 17 12C17 10.9 16.1 10 15 10ZM9 10C7.9 10 7 10.9 7 12C7 13.1 7.9 14 9 14C10.1 14 11 13.1 11 12C11 10.9 10.1 10 9 10ZM15 16C13.9 16 13 16.9 13 18C13 19.1 13.9 20 15 20C16.1 20 17 19.1 17 18C17 16.9 16.1 16 15 16ZM9 16C7.9 16 7 16.9 7 18C7 19.1 7.9 20 9 20C10.1 20 11 19.1 11 18C11 16.9 10.1 16 9 16Z\"></path></svg>", "draghorizontal-24x16": "<svg viewBox=\"0 0 24 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M18 9C19.1 9 20 9.9 20 11C20 12.1 19.1 13 18 13C16.9 13 16 12.1 16 11C16 9.9 16.9 9 18 9ZM20 5C20 3.9 19.1 3 18 3C16.9 3 16 3.9 16 5C16 6.1 16.9 7 18 7C19.1 7 20 6.1 20 5ZM14 11C14 9.9 13.1 9 12 9C10.9 9 10 9.9 10 11C10 12.1 10.9 13 12 13C13.1 13 14 12.1 14 11ZM14 5C14 3.9 13.1 3 12 3C10.9 3 10 3.9 10 5C10 6.1 10.9 7 12 7C13.1 7 14 6.1 14 5ZM8 11C8 9.9 7.1 9 6 9C4.9 9 4 9.9 4 11C4 12.1 4.9 13 6 13C7.1 13 8 12.1 8 11ZM8 5C8 3.9 7.1 3 6 3C4.9 3 4 3.9 4 5C4 6.1 4.9 7 6 7C7.1 7 8 6.1 8 5Z\"></path></svg>", "editsmall-16x16": "<svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M13.59 4.5884L11.42 2.4184C11.03 2.0284 10.52 1.8284 10.01 1.8284C9.5 1.8284 8.99 2.0284 8.6 2.4184L3.76 7.2384C2.63 8.3684 2 9.8884 2 11.4784V12.9884C2 13.5384 2.45 13.9884 3 13.9884H4.51C6.1 13.9884 7.63 13.3584 8.75 12.2284L13.58 7.3984C14.36 6.6184 14.36 5.3484 13.58 4.5684L13.59 4.5884ZM7.35 10.8284C6.59 11.5884 5.59 11.9984 4.52 11.9984H4.01V11.4884C4.01 10.4184 4.43 9.4184 5.18 8.6584L7.72 6.1184L9.89 8.2884L7.35 10.8284ZM11.3 6.8784L9.13 4.7084L10.01 3.8284L12.18 5.9984L11.3 6.8784Z\"></path></svg>", "expand-16x16": "<svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 14L5 13L10 8L5 3L6 2L12 8L6 14Z\"></path></svg>", "expanddetails-16x16": "<svg viewBox=\"0 0 16 16\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M13 7H9V3H7V7H3V9H7V13H9V9H13V7Z\"></path><