survey-creator-react
Version:
A white-label drag-and-drop form builder for React that lets you design complex, interactive forms and surveys without writing code. It generates JSON schemas used by the SurveyJS Form Library to render dynamic forms in your React app.
1 lines • 715 kB
Source Map (JSON)
{"version":3,"file":"survey-creator-react.mjs","sources":["../../src/TabbedMenu.tsx","../../src/SurveyCreator.tsx","../../src/ModelElement.tsx","../../src/adorners/Row.tsx","../../src/events.ts","../../src/adorners/Question.tsx","../../src/adorners/QuestionHeader.tsx","../../src/adorners/QuestionFooter.tsx","../../src/ActionButton.tsx","../../src/adorners/QuestionBanner.tsx","../../src/adorners/QuestionDropdown.tsx","../../src/adorners/QuestionImage.tsx","../../src/adorners/QuestionRating.tsx","../../src/adorners/QuestionWidget.tsx","../../src/adorners/CellQuestion.tsx","../../src/adorners/CellQuestionDropdown.tsx","../../src/adorners/Page.tsx","../../src/AddQuestionButton.tsx","../../src/adorners/Panel.tsx","../../src/LogoImage.tsx","../../src/QuestionLinkValue.tsx","../../src/QuestionEmbeddedSurvey.tsx","../../src/QuestionEditorContent.tsx","../../src/ItemValueWrapper.tsx","../../src/ImageItemValueWrapper.tsx","../../src/MatrixCellWrapper.tsx","../../src/Results.tsx","../../src/toolbox/ToolboxItem.tsx","../../src/toolbox/ToolboxItemGroup.tsx","../../src/toolbox/ToolboxCategory.tsx","../../src/toolbox/ToolboxList.tsx","../../src/components/Search.tsx","../../src/toolbox/AdaptiveToolbox.tsx","../../src/Navigation.tsx","../../src/side-bar/TabButton.tsx","../../src/side-bar/TabControl.tsx","../../src/side-bar/SideBarDefaultHeader.tsx","../../src/side-bar/SideBarPropertyGridHeader.tsx","../../src/side-bar/SideBarHeader.tsx","../../src/side-bar/SideBar.tsx","../../src/tabs/translation/TranslationLineSkeleton.tsx","../../src/tabs/translation/TranslateFromAction.tsx","../../src/StringEditor.tsx","../../src/QuestionError.tsx","../../src/tabs/logic-operator.tsx","../../src/PageNavigator.tsx","../../src/components/SurfacePlaceholder.tsx","../../src/tabs/Designer.tsx","../../src/tabs/JsonEditorTextarea.tsx","../../src/tabs/JsonEditorAce.tsx","../../src/tabs/Logic.tsx","../../src/tabs/SurveySimulator.tsx","../../src/tabs/Preview.tsx","../../src/side-bar/PropertyGridPlaceholder.tsx","../../src/tabs/Theme.tsx","../../src/tabs/translation/Translation.tsx","../../src/side-bar/ObjectSelector.tsx","../../src/side-bar/PropertyGrid.tsx","../../src/components/ComponentContainer.tsx","../../src/Switcher.tsx","../../src/tabs/JsonErrorItem.tsx","../../src/custom-questions/SpinEditor.tsx","../../src/custom-questions/ColorItem.tsx","../../src/custom-questions/ColorQuestion.tsx","../../src/custom-questions/FileEditQuestion.tsx","../../src/custom-questions/TextWithResetQuestion.tsx","../../src/custom-questions/BooleanSwitch.tsx","../../src/entries/index-wc.ts"],"sourcesContent":["import * as React from \"react\";\nimport * as ReactDOM from \"react-dom\";\nimport { TabbedMenuItem, TabbedMenuContainer } from \"survey-creator-core\";\nimport { Base, ResponsivityManager } from \"survey-core\";\nimport { attachKey2click, ReactElementFactory, SurveyElementBase, SvgIcon } from \"survey-react-ui\";\n\nexport interface ITabbedMenuComponentProps {\n model: TabbedMenuContainer;\n}\n\nexport class TabbedMenuComponent extends SurveyElementBase<\n ITabbedMenuComponentProps,\n any\n> {\n private rootRef: React.RefObject<HTMLDivElement>;\n\n private get model() {\n return this.props.model;\n }\n\n protected getStateElement(): Base {\n return this.model;\n }\n\n constructor(props) {\n super(props);\n this.rootRef = React.createRef();\n }\n\n renderElement(): React.JSX.Element {\n const items = this.model.renderedActions.map((item) => <TabbedMenuItemWrapper item={item} key={item.renderedId} />);\n return (\n <div ref={this.rootRef} className=\"svc-tabbed-menu\" role=\"tablist\" style={this.model.getRootStyle()}>\n {items}\n </div>\n );\n }\n componentDidUpdate(prevProps: any, prevState: any): void {\n super.componentDidUpdate(prevProps, prevState);\n const container: HTMLDivElement = this.rootRef.current;\n if (!container) return;\n this.model.initResponsivityManager(container);\n }\n componentDidMount() {\n super.componentDidMount();\n const container: HTMLDivElement = this.rootRef.current;\n if (!container) return;\n this.model.initResponsivityManager(container);\n }\n componentWillUnmount() {\n this.model.resetResponsivityManager();\n super.componentWillUnmount();\n }\n}\n\nclass TabbedMenuItemWrapper extends SurveyElementBase<\n any,\n any\n> {\n private ref: React.RefObject<HTMLDivElement>;\n constructor(props) {\n super(props);\n this.ref = React.createRef();\n this.state = { changed: 0 };\n }\n\n private get item(): TabbedMenuItem {\n return this.props.item;\n }\n\n protected getStateElement(): Base {\n return this.item;\n }\n\n renderElement(): React.JSX.Element {\n let css: string = \"svc-tabbed-menu-item-container\";\n if (this.item.css) {\n css += \" \" + this.item.css;\n }\n css += (!this.item.isVisible ? \" sv-action--hidden\" : \"\");\n\n const component = ReactElementFactory.Instance.createElement(\n this.item.component || \"svc-tabbed-menu-item\",\n { item: this.item }\n );\n\n return (\n <span key={this.item.id} className={css} ref={this.ref}>\n <div className=\"sv-action__content\">\n {component}\n </div>\n </span>\n );\n }\n componentDidMount(): void {\n super.componentDidMount();\n this.item.updateModeCallback = (mode, callback) => {\n const update = () => {\n if (this.item.mode == mode) {\n this.setState({ changed: this.state.changed + 1 });\n } else {\n this.item.mode = mode;\n }\n };\n queueMicrotask(() => {\n if ((ReactDOM as any)[\"flushSync\"]) {\n (ReactDOM as any)[\"flushSync\"](() => {\n update();\n });\n } else {\n update();\n }\n queueMicrotask(() => {\n callback(mode, this.ref.current);\n });\n });\n };\n this.item.afterRender();\n }\n componentWillUnmount(): void {\n super.componentWillUnmount();\n this.item.updateModeCallback = undefined;\n }\n}\n\nexport interface ITabbedMenuItemComponentProps {\n item: TabbedMenuItem;\n}\nexport class TabbedMenuItemComponent extends SurveyElementBase<\n ITabbedMenuItemComponentProps,\n any\n> {\n get item(): TabbedMenuItem {\n return this.props.item;\n }\n protected getStateElement(): Base {\n return this.item;\n }\n\n render(): React.JSX.Element {\n const item = this.item;\n return (attachKey2click(\n <div\n role=\"tab\"\n id={\"tab-\" + item.id}\n aria-selected={item.active}\n aria-controls={\"scrollableDiv-\" + item.id}\n className={item.getRootCss()}\n onClick={() => item.doAction()}\n >\n {item.hasTitle ? <span className={item.getTitleCss()}>{item.title}</span> : null}\n {item.hasIcon ? <SvgIcon iconName={item.iconName} className={item.getIconCss()} size={\"auto\"} title={item.tooltip || item.title}></SvgIcon> : null}\n </div>\n )\n );\n }\n}\n\nReactElementFactory.Instance.registerElement(\n \"svc-tabbed-menu-item\",\n (props) => {\n return React.createElement(TabbedMenuItemComponent, props);\n }\n);\nexport default TabbedMenuComponent;\n","import * as React from \"react\";\nimport * as ReactDOM from \"react-dom\";\n\nimport {\n Base,\n Question,\n SurveyError,\n SurveyModel\n} from \"survey-core\";\nimport {\n NotifierComponent,\n SurveyActionBar,\n ReactElementFactory,\n ReactQuestionFactory,\n SurveyElementBase,\n SurveyLocStringViewer,\n Survey,\n SvgBundleComponent,\n PopupModal\n} from \"survey-react-ui\";\nimport {\n ICreatorOptions,\n SurveyCreatorModel,\n ITabbedMenuItem,\n assign\n} from \"survey-creator-core\";\nimport { TabbedMenuComponent } from \"./TabbedMenu\";\n\ninterface ISurveyCreatorComponentProps {\n creator: SurveyCreator;\n style?: any;\n}\n\nexport class SurveyCreatorComponent extends SurveyElementBase<\n ISurveyCreatorComponentProps,\n any\n> {\n constructor(props: ISurveyCreatorComponentProps) {\n super(props);\n this.rootNode = React.createRef();\n }\n get creator(): SurveyCreatorModel {\n return this.props.creator;\n }\n protected getStateElement(): Base {\n return this.creator;\n }\n get style(): any {\n return this.props.style;\n }\n\n componentDidUpdate(prevProps: any, prevState: any): void {\n super.componentDidUpdate(prevProps, prevState);\n if (this.creator !== prevProps.creator) {\n if (prevProps.creator) {\n prevProps.creator.unsubscribeRootElement();\n }\n if (this.creator && this.rootNode.current) {\n this.creator.setRootElement(this.rootNode.current);\n }\n }\n }\n\n componentDidMount() {\n super.componentDidMount();\n this.creator.setRootElement(this.rootNode.current);\n }\n componentWillUnmount() {\n super.componentWillUnmount();\n this.creator.unsubscribeRootElement();\n }\n private rootNode: React.RefObject<HTMLDivElement>;\n\n renderElement() {\n const creator: SurveyCreatorModel = this.props.creator;\n if (creator.isCreatorDisposed) return null;\n const areaClassName = \"svc-full-container svc-creator__area svc-flex-column\" + (this.props.creator.haveCommercialLicense ? \"\" : \" svc-creator__area--with-banner\");\n const contentWrapperClassName = \"svc-creator__content-wrapper svc-flex-row\" + (this.props.creator.isMobileView ? \" svc-creator__content-wrapper--footer-toolbar\" : \"\");\n const fullContainerClassName = \"svc-flex-row svc-full-container\" + (\" svc-creator__side-bar--\" + this.creator.sidebarLocation);\n const creatorStyles = {};\n assign(creatorStyles, this.style, this.props.creator.themeVariables);\n let licenseBanner = null;\n if (!this.props.creator.haveCommercialLicense) {\n const htmlValue = { __html: this.props.creator.licenseText };\n licenseBanner = (\n <div className=\"svc-creator__banner\">\n <span className=\"svc-creator__non-commercial-text\" dangerouslySetInnerHTML={htmlValue}></span>\n </div>\n );\n }\n //AM: width unrecognized by react\n return (\n <div className={this.creator.getRootCss()} ref={this.rootNode} style={creatorStyles}>\n <SvgBundleComponent></SvgBundleComponent>\n <PopupModal></PopupModal>\n <div className={areaClassName}>\n <div className={fullContainerClassName}>\n <div className=\"svc-flex-column svc-flex-row__element svc-flex-row__element--growing\">\n <div className=\"svc-top-bar\">\n {(creator.showTabs ?\n <div className=\"svc-tabbed-menu-wrapper\">\n <TabbedMenuComponent model={creator.tabbedMenu}></TabbedMenuComponent>\n </div> : null)}\n {(creator.showToolbar ?\n <div className=\"svc-toolbar-wrapper\">\n <SurveyActionBar model={creator.toolbar}></SurveyActionBar>\n </div>\n : null)}\n </div>\n <div className={contentWrapperClassName}>\n <div className=\"svc-creator__content-holder svc-flex-column\">\n {this.renderActiveTab()}\n </div>\n </div>\n <div className=\"svc-footer-bar\">\n {(creator.isMobileView ?\n <div className=\"svc-toolbar-wrapper\">\n <SurveyActionBar model={creator.footerToolbar}></SurveyActionBar>\n </div>\n : null)}\n </div>\n </div>\n {this.renderSidebar()}\n </div>\n {licenseBanner}\n <NotifierComponent notifier={creator.notifier}></NotifierComponent>\n </div>\n </div>\n );\n }\n renderActiveTab() {\n const creator: SurveyCreatorModel = this.props.creator;\n for (var i = 0; i < creator.tabs.length; i++) {\n if (creator.tabs[i].id === creator.activeTab) {\n return this.renderCreatorTab(creator.tabs[i]);\n }\n }\n return null;\n }\n renderCreatorTab(tab: ITabbedMenuItem) {\n if (tab.visible === false) {\n return null;\n }\n const creator: SurveyCreatorModel = this.props.creator;\n const component = !!tab.renderTab\n ? tab.renderTab()\n : ReactElementFactory.Instance.createElement(tab.componentContent, {\n creator: creator,\n survey: creator.survey,\n data: tab.data.model\n });\n const className = \"svc-creator-tab\" + (creator.toolboxLocation == \"right\" ? \" svc-creator__toolbox--right\" : \"\");\n return (\n <div\n role=\"tabpanel\"\n key={tab.id}\n id={\"scrollableDiv-\" + tab.id}\n aria-labelledby={\"tab-\" + tab.id}\n className={className}\n >\n {component}\n </div>\n );\n }\n renderSidebar() {\n if (!!this.creator.isSidebarVisible) {\n return ReactElementFactory.Instance.createElement(\"svc-side-bar\", { model: this.creator.sidebar });\n } else {\n return null;\n }\n }\n}\n\nexport class SurveyCreator extends SurveyCreatorModel {\n constructor(options: ICreatorOptions = {}, options2?: ICreatorOptions) {\n super(options, options2);\n }\n public render(target: string | HTMLElement) {\n // eslint-disable-next-line no-console\n console.error(\"The render method is deprecated. Use SurveyCreatorComponent instead.\");\n }\n\n //ISurveyCreator\n public createQuestionElement(question: Question): React.JSX.Element {\n return ReactQuestionFactory.Instance.createQuestion(\n question.isDefaultRendering()\n ? question.getTemplate()\n : question.getComponentName(),\n {\n question: question,\n isDisplayMode: question.isReadOnly,\n creator: this\n }\n );\n }\n public renderError(\n key: string,\n error: SurveyError,\n cssClasses: any\n ): React.JSX.Element {\n return (\n <div key={key}>\n <span className={cssClasses.error.icon} aria-hidden=\"true\" />\n <span className={cssClasses.error.item}>\n <SurveyLocStringViewer locStr={error.locText} />\n </span>\n </div>\n );\n }\n public questionTitleLocation(): string {\n return this.survey.questionTitleLocation;\n }\n public questionErrorLocation(): string {\n return this.survey.questionErrorLocation;\n }\n}\n\nReactElementFactory.Instance.registerElement(\"survey-widget\", (props) => {\n return React.createElement(Survey, props);\n});\n","import { SurveyElementBase } from \"survey-react-ui\";\n\nexport class CreatorModelElement<P, S> extends SurveyElementBase<P, S> {\n constructor(props: P) {\n super(props);\n this.createModel(props);\n }\n shouldComponentUpdate(nextProps: any, nextState: any): boolean {\n const result = super.shouldComponentUpdate(nextProps, nextState);\n if (result) {\n if (this.needUpdateModel(nextProps)) {\n this.createModel(nextProps);\n }\n }\n return result;\n }\n protected createModel(props: any): void { }\n protected needUpdateModel(nextProps: any): boolean {\n const names = this.getUpdatedModelProps();\n if (!Array.isArray(names)) return true;\n for (var i = 0; i < names.length; i++) {\n const key = names[i];\n if (typeof key === \"object\") {\n const currentProp = this.props[key.name];\n const nextProp = nextProps[key.name];\n if (key.deepEqual) {\n if (this.props[key.name] === nextProps[key.name]) return false;\n const currentPropKeys = Object.keys(currentProp || {});\n if (currentPropKeys.length !== Object.keys(nextProp || {}).length) return true;\n return currentPropKeys.some(key => currentProp[key] != nextProp[key]);\n } else {\n return currentProp !== nextProp;\n }\n } else {\n if (this.props[key] !== nextProps[key]) return true;\n }\n }\n return false;\n }\n protected getUpdatedModelProps(): Array<string | { name: string, deepEqual?: boolean }> {\n return undefined;\n }\n}","import { RowViewModel } from \"survey-creator-core\";\nimport * as React from \"react\";\nimport { Base, QuestionRowModel } from \"survey-core\";\nimport { ReactElementFactory } from \"survey-react-ui\";\nimport { CreatorModelElement } from \"../ModelElement\";\n\ninterface RowWrapperComponentProps {\n element: React.JSX.Element;\n componentData: any;\n row: QuestionRowModel;\n}\n\nexport class RowWrapper extends CreatorModelElement<\n RowWrapperComponentProps,\n any\n> {\n model: RowViewModel;\n constructor(props: RowWrapperComponentProps) {\n super(props);\n }\n protected createModel(props: any): void {\n if (!!this.model) {\n this.model.dispose();\n }\n this.model = new RowViewModel(\n props.componentData.creator,\n props.row,\n null\n );\n }\n protected getUpdatedModelProps(): Array<string | { name: string, deepEqual?: boolean }> {\n return [\"row\", { name: \"componentData\", deepEqual: true }];\n }\n protected getStateElement(): Base {\n return this.model;\n }\n\n componentDidMount(): void {\n super.componentDidMount();\n this.model.subscribeElementChanges();\n }\n componentWillUnmount(): void {\n this.model.unsubscribeElementChanges();\n super.componentWillUnmount();\n }\n\n render(): React.JSX.Element {\n return (\n <div\n key={\"svc-row-\" + this.props.row.id}\n className={this.model.cssClasses}\n >\n <div className=\"svc-row__drop-indicator svc-row__drop-indicator--top\"></div>\n <div className=\"svc-row__drop-indicator svc-row__drop-indicator--bottom\"></div>\n {this.props.element}\n </div>\n );\n }\n}\n\nReactElementFactory.Instance.registerElement(\n \"svc-row\",\n (props: RowWrapperComponentProps) => {\n return React.createElement(RowWrapper, props);\n }\n);\n","import { IPortableDragEvent, IPortableMouseEvent } from \"survey-creator-core\";\n\nexport class ReactMouseEvent implements IPortableMouseEvent {\n constructor(public event: React.MouseEvent<HTMLDivElement, MouseEvent>) {}\n stopPropagation() {\n this.event.stopPropagation();\n //this.event.nativeEvent.stopPropagation();\n //this.event.nativeEvent.stopImmediatePropagation();\n }\n preventDefault() {\n this.event.preventDefault();\n //this.event.nativeEvent.preventDefault();\n }\n get cancelBubble(): boolean {\n //return this.event.cancelBubble;\n return false;\n }\n set cancelBubble(value: boolean) {\n //this.event.cancelBubble = value;\n }\n get target(): EventTarget | null {\n return this.event.target;\n }\n get currentTarget(): EventTarget | null {\n return this.event.currentTarget;\n }\n get clientX(): number {\n return this.event.clientX;\n }\n get clientY(): number {\n return this.event.clientY;\n }\n get offsetX(): number {\n return this.event.nativeEvent.offsetX;\n }\n get offsetY(): number {\n return this.event.nativeEvent.offsetY;\n }\n}\n\nexport class ReactDragEvent extends ReactMouseEvent\n implements IPortableDragEvent {\n constructor(public event: React.DragEvent<HTMLDivElement>) {\n super(event);\n }\n\n get dataTransfer(): DataTransfer {\n return this.event.dataTransfer;\n }\n}\n","import { QuestionAdornerViewModel, toggleHovered } from \"survey-creator-core\";\nimport * as React from \"react\";\nimport { ReactDragEvent, ReactMouseEvent } from \"../events\";\nimport { Base, PanelModel, Question, SurveyElementCore } from \"survey-core\";\nimport {\n SurveyActionBar,\n ReactElementFactory,\n SurveyQuestion,\n attachKey2click,\n SvgIcon,\n Popup,\n SurveyElementBase,\n TitleElement\n} from \"survey-react-ui\";\nimport { CreatorModelElement } from \"../ModelElement\";\n\nexport interface QuestionAdornerComponentProps {\n element: React.JSX.Element;\n question: Question;\n componentData: any;\n}\n\nfunction QuestionElementContentFunc(props: { element: React.JSX.Element }): React.ReactElement {\n return props.element;\n}\n\nconst QuestionElementContent = React.memo(QuestionElementContentFunc);\nQuestionElementContent.displayName = \"QuestionElementContent\";\n\nexport class QuestionAdornerComponent extends CreatorModelElement<\n QuestionAdornerComponentProps,\n any\n> {\n private modelValue: QuestionAdornerViewModel;\n protected rootRef: React.RefObject<HTMLDivElement>;\n constructor(props: QuestionAdornerComponentProps) {\n super(props);\n this.rootRef = React.createRef();\n }\n protected createModel(props: QuestionAdornerComponentProps): void {\n if (this.model) {\n this.model.attachToUI(props.question, this.rootRef.current);\n } else {\n this.modelValue = this.createQuestionViewModel(props);\n }\n }\n protected createQuestionViewModel(props: any): QuestionAdornerViewModel {\n return new QuestionAdornerViewModel(\n props.componentData,\n props.question,\n null\n );\n }\n protected getUpdatedModelProps(): string[] {\n return [\"question\", \"componentData\"];\n }\n public get model(): QuestionAdornerViewModel {\n return this.modelValue;\n }\n protected getStateElement(): Base {\n return this.model;\n }\n\n renderElement(): React.JSX.Element {\n const allowInteractions = this.model.element\n .isInteractiveDesignElement;\n const titleForCollapsedState = this.renderQuestionTitle();\n const content = this.renderContent(allowInteractions);\n return (\n <div\n ref={this.rootRef}\n data-sv-drop-target-survey-element={this.model.element.name || null}\n className={this.model.rootCss()}\n onDoubleClick={e => { allowInteractions && this.model.dblclick(e.nativeEvent); e.stopPropagation(); }}\n onMouseLeave={e => allowInteractions && this.model.hover(e.nativeEvent, e.currentTarget)}\n onMouseOver={e => allowInteractions && this.model.hover(e.nativeEvent, e.currentTarget)}\n >\n {titleForCollapsedState}\n {content}\n </div>\n );\n }\n protected disableTabStop() {\n return true;\n }\n protected renderContent(allowInteractions: boolean): React.JSX.Element {\n var content = this.model.needToRenderContent ? this.renderElementContent() : null;\n //if (!allowInteractions) return <>{content}{this.renderFooter()}</>;\n return attachKey2click(\n <div\n className={this.model.css()}\n onClick={(e) => this.model.select(this.model, new ReactMouseEvent(e))}\n >\n <div className=\"svc-question__drop-indicator svc-question__drop-indicator--left\"></div>\n <div className=\"svc-question__drop-indicator svc-question__drop-indicator--right\"></div>\n <div className=\"svc-question__drop-indicator svc-question__drop-indicator--top\"></div>\n <div className=\"svc-question__drop-indicator svc-question__drop-indicator--bottom\"></div>\n {allowInteractions ? this.renderHeader() : null}\n {content}\n {this.model.needToRenderContent ? this.renderFooter() : null}\n </div>,\n undefined, { disableTabStop: this.disableTabStop() });\n }\n protected renderHeader(): React.JSX.Element {\n return ReactElementFactory.Instance.createElement(\"svc-question-header\", { model: this.model });\n }\n protected renderFooter(): React.JSX.Element {\n const allowInteractions = this.model.element\n .isInteractiveDesignElement;\n return allowInteractions ? ReactElementFactory.Instance.createElement(\"svc-question-footer\", { className: \"svc-question__content-actions\", model: this.model }) : null;\n }\n protected renderCarryForwardBanner(): React.JSX.Element {\n if (!this.model.isBannerShowing) return null;\n return ReactElementFactory.Instance.createElement(\"svc-question-banner\", this.model.createBannerParams());\n }\n\n protected renderQuestionTitle(): React.JSX.Element {\n if (!this.model.showHiddenTitle) return null;\n const element = this.model.element as Question | PanelModel;\n return (\n <div\n ref={node => node && (!this.model.renderedCollapsed ?\n node.setAttribute(\"inert\", \"\") : node.removeAttribute(\"inert\")\n )} className={this.model.cssCollapsedHiddenHeader} >\n {(\n element.hasTitle ?\n <TitleElement element={element} renderActions={false}></TitleElement> :\n <div\n className={this.model.cssCollapsedHiddenTitle} >\n <span className=\"svc-fake-title\">{element.name}</span>\n </div>\n )}\n </div>\n );\n }\n\n protected renderElementContent(): React.JSX.Element {\n return (\n <>\n <QuestionElementContent element={this.props.element} />\n {this.renderElementPlaceholder()}\n {this.renderCarryForwardBanner()}\n </>\n );\n }\n componentDidMount() {\n super.componentDidMount();\n this.model.attachToUI(this.props.question, this.rootRef.current);\n }\n renderElementPlaceholder(): React.JSX.Element {\n if (!this.model.isEmptyElement) {\n return null;\n }\n return (\n <div className=\"svc-panel__placeholder_frame-wrapper\">\n <div className=\"svc-panel__placeholder_frame\">\n <div className=\"svc-panel__placeholder\">\n {this.model.placeholderText}\n </div>\n </div>\n </div>\n );\n }\n componentWillUnmount(): void {\n super.componentWillUnmount();\n this.model.detachFromUI();\n }\n}\n\nReactElementFactory.Instance.registerElement(\n \"svc-question\",\n (props: QuestionAdornerComponentProps) => {\n return React.createElement(QuestionAdornerComponent, props);\n }\n);\n","import { QuestionAdornerViewModel, toggleHovered } from \"survey-creator-core\";\nimport * as React from \"react\";\nimport { ReactDragEvent, ReactMouseEvent } from \"../events\";\nimport { Base, Question } from \"survey-core\";\nimport {\n SurveyActionBar,\n ReactElementFactory,\n SurveyElementBase,\n SurveyQuestion,\n attachKey2click,\n SvgIcon,\n Popup\n} from \"survey-react-ui\";\n\nexport interface QuestionWrapperHeaderProps {\n className?: string;\n model: QuestionAdornerViewModel;\n}\n\nexport class QuestionWrapperHeader extends React.Component<QuestionWrapperHeaderProps, any> {\n render(): React.JSX.Element {\n if (!this.props.model.allowDragging) return null;\n return (\n <div className={\"svc-question__drag-area\"}\n onPointerDown={(event: any) =>\n this.props.model.onPointerDown(event)\n }\n >\n <SvgIcon className=\"svc-question__drag-element\" size={\"auto\"} iconName={\"icon-drag-area-indicator_24x16\"}></SvgIcon>\n <div className=\"svc-question__top-actions\">\n <SurveyActionBar model={this.props.model.topActionContainer} handleClick={false}></SurveyActionBar>\n </div>\n </div>\n );\n }\n}\n\nReactElementFactory.Instance.registerElement(\n \"svc-question-header\",\n (props: QuestionWrapperHeaderProps) => {\n return React.createElement(QuestionWrapperHeader, props);\n }\n);\n","import { QuestionAdornerViewModel, toggleHovered } from \"survey-creator-core\";\nimport * as React from \"react\";\nimport { ReactDragEvent, ReactMouseEvent } from \"../events\";\nimport {\n SurveyActionBar,\n ReactElementFactory,\n} from \"survey-react-ui\";\n\nexport interface QuestionWrapperFooterProps {\n className?: string;\n model: QuestionAdornerViewModel;\n}\nexport class QuestionWrapperFooter extends React.Component<QuestionWrapperFooterProps, any> {\n render(): React.JSX.Element {\n return (<div className={this.props.className} onFocus={(e) => this.props.model.select(this.props.model, new ReactMouseEvent(e as any))}>\n <SurveyActionBar model={this.props.model.actionContainer} handleClick={false}></SurveyActionBar>\n </div>);\n }\n}\n\nReactElementFactory.Instance.registerElement(\n \"svc-question-footer\",\n (props: QuestionWrapperFooterProps) => {\n return React.createElement(QuestionWrapperFooter, props);\n }\n);\n\n","import * as React from \"react\";\nimport { CssClassBuilder } from \"survey-core\";\nimport { attachKey2click, ReactElementFactory, SurveyElementBase, SvgIcon, } from \"survey-react-ui\";\n\ninterface IActionButtonProps {\n classes?;\n click: () => void;\n selected?: boolean;\n disabled?: boolean;\n text?: string;\n title?: string;\n iconName?: string;\n allowBubble?: boolean;\n}\nexport class ActionButton extends SurveyElementBase<IActionButtonProps, any> {\n renderElement(): React.JSX.Element {\n const classes = new CssClassBuilder()\n .append(this.props.classes)\n .append(\"svc-action-button\")\n .append(\"svc-action-button--selected\", !!this.props.selected)\n .append(\"svc-action-button--disabled\", !!this.props.disabled)\n .toString();\n if (this.props.iconName) {\n return this.renderIcon(classes);\n }\n return this.renderButtonText(classes);\n }\n\n renderButtonText(classes): React.JSX.Element {\n if (this.props.disabled) {\n return <span className={classes}>{this.props.text}</span>;\n }\n return (\n <>\n {attachKey2click(\n <span\n role=\"button\"\n className={classes}\n onClick={(e) => {\n if (!this.props.allowBubble) {\n e.stopPropagation();\n }\n this.props.click();\n }}\n title={this.props.title}\n >\n {this.props.text}\n </span>\n )}\n </>\n );\n }\n renderIcon(classes): React.JSX.Element {\n classes += \" svc-action-button--icon\";\n if (this.props.disabled) {\n return <span className={classes}><SvgIcon size={\"auto\"} iconName={this.props.iconName}></SvgIcon></span>;\n }\n return (\n <>\n {attachKey2click(\n <span className={classes}\n onClick={(e) => {\n if (!this.props.allowBubble) {\n e.stopPropagation();\n }\n this.props.click();\n }}\n title={this.props.title}\n >\n <SvgIcon size={\"auto\"} iconName={this.props.iconName}></SvgIcon>\n </span>\n )}\n </>\n );\n }\n}\nReactElementFactory.Instance.registerElement(\"svc-action-button\", (props: any) => { return React.createElement(ActionButton, props); });","import { QuestionBannerParams } from \"survey-creator-core\";\nimport * as React from \"react\";\nimport { ReactElementFactory } from \"survey-react-ui\";\nimport { ActionButton } from \"../ActionButton\";\n\nexport class QuestionBanner extends React.Component<QuestionBannerParams, any> {\n render(): React.JSX.Element {\n return (\n <div className=\"svc-carry-forward-panel-wrapper\"><div className=\"svc-carry-forward-panel\">\n <span>{this.props.text}{\" \"}</span>\n <span className=\"svc-carry-forward-panel__link\">\n <ActionButton click={() => this.props.onClick()} text={this.props.actionText}></ActionButton>\n </span>\n </div></div>);\n }\n}\n\nReactElementFactory.Instance.registerElement(\n \"svc-question-banner\",\n (props: QuestionBannerParams) => {\n return React.createElement(QuestionBanner, props);\n }\n);\n\n","import * as React from \"react\";\nimport { QuestionDropdownAdornerViewModel } from \"survey-creator-core\";\nimport { ItemValue, QuestionDropdownModel, QuestionSelectBase, SurveyModel } from \"survey-core\";\nimport { ReactElementFactory, ReactSurveyElementsWrapper } from \"survey-react-ui\";\nimport {\n QuestionAdornerComponent,\n QuestionAdornerComponentProps\n} from \"./Question\";\nimport { ActionButton } from \"../ActionButton\";\n\nexport class QuestionDropdownAdornerComponent extends QuestionAdornerComponent {\n constructor(props: QuestionAdornerComponentProps) {\n super(props);\n }\n protected createQuestionViewModel(props: any): QuestionDropdownAdornerViewModel {\n return new QuestionDropdownAdornerViewModel(\n props.componentData,\n props.question as QuestionDropdownModel,\n null\n );\n }\n public get dropdownModel(): QuestionDropdownAdornerViewModel {\n return this.model as QuestionDropdownAdornerViewModel;\n }\n public get question(): QuestionSelectBase {\n return this.dropdownModel.question as QuestionSelectBase;\n }\n\n renderElementPlaceholder(): React.JSX.Element {\n const textStyle = (this.question as any).textStyle;\n return (\n <div\n className=\"svc-question__dropdown-choices--wrapper\">\n <div>\n <div className=\"svc-question__dropdown-choices\">\n {(this.dropdownModel.getRenderedItems() || []).map(\n (item: ItemValue, index: number) => (\n <div\n className={this.dropdownModel.getChoiceCss()}\n key={`editable_choice_${index}`}\n >\n {ReactSurveyElementsWrapper.wrapItemValue(this.question.survey as SurveyModel,\n ReactElementFactory.Instance.createElement(\n this.dropdownModel.itemComponent,\n {\n key: item.value,\n question: this.question,\n cssClasses: this.question.cssClasses,\n isDisplayMode: true,\n item: item,\n textStyle: textStyle,\n index: index,\n isChecked: this.question.value === item.value\n }\n ),\n this.question,\n item\n )}\n </div>\n )\n )}\n </div>\n {this.dropdownModel.needToCollapse ?\n <ActionButton\n click={this.dropdownModel.switchCollapse}\n text={this.dropdownModel.getButtonText()}\n allowBubble={true}\n ></ActionButton> :\n null\n }\n </div>\n </div>\n );\n }\n}\n\nReactElementFactory.Instance.registerElement(\n \"svc-dropdown-question\",\n (props: QuestionAdornerComponentProps) => {\n return React.createElement(QuestionDropdownAdornerComponent, props);\n }\n);\n","import {\n QuestionImageAdornerViewModel,\n QuestionAdornerViewModel\n} from \"survey-creator-core\";\nimport * as React from \"react\";\nimport { attachKey2click, LoadingIndicatorComponent, ReactElementFactory, ReactQuestionFactory, SvgIcon } from \"survey-react-ui\";\nimport {\n QuestionAdornerComponent,\n QuestionAdornerComponentProps\n} from \"./Question\";\nimport { Base } from \"survey-core\";\n\nexport class QuestionImageAdornerComponent extends QuestionAdornerComponent {\n protected createQuestionViewModel(props: any): QuestionAdornerViewModel {\n return new QuestionImageAdornerViewModel(\n props.componentData,\n props.question as any,\n null);\n }\n public get imageModel(): QuestionImageAdornerViewModel {\n return this.model as QuestionImageAdornerViewModel;\n }\n protected renderHeader(): React.JSX.Element {\n return (<React.Fragment>\n <input\n type=\"file\"\n aria-hidden=\"true\"\n tabIndex={-1}\n accept={this.imageModel.acceptedTypes}\n className=\"svc-choose-file-input\"\n style={{\n position: \"absolute\",\n opacity: 0,\n width: \"1px\",\n height: \"1px\",\n overflow: \"hidden\"\n }}\n />\n\n {super.renderHeader()}\n </React.Fragment>);\n }\n renderLoadingPlaceholder(): React.JSX.Element {\n return (<div className=\"svc-image-question__loading-placeholder\">\n <div className=\"svc-image-question__loading\">\n <LoadingIndicatorComponent></LoadingIndicatorComponent>\n </div>\n </div>);\n }\n renderChooseButton(): React.JSX.Element {\n return (<div className=\"svc-image-question-controls\">\n {this.model.allowEdit ? attachKey2click(<span\n className=\"svc-context-button\"\n onClick={() => this.imageModel.chooseFile(this.imageModel)}\n >\n <SvgIcon size={\"auto\"} iconName={\"icon-choosefile\"}></SvgIcon>\n </span>) : null}\n </div>);\n }\n renderElementPlaceholder(): React.JSX.Element {\n return this.imageModel.isUploading ? this.renderLoadingPlaceholder() : this.renderChooseButton();\n }\n protected getStateElements(): Array<Base> {\n return [this.model, this.imageModel.filePresentationModel];\n }\n\n protected renderElementContent(): React.JSX.Element {\n if (this.imageModel.isEmptyElement) {\n const fileQuestion = ReactQuestionFactory.Instance.createQuestion(\"file\", {\n creator: this.imageModel.question.survey,\n isDisplayMode: false,\n question: this.imageModel.filePresentationModel\n });\n return (<>\n {fileQuestion}\n </>);\n } else {\n return (\n <>\n {this.props.element}\n {this.renderElementPlaceholder()}\n </>\n );\n }\n }\n}\n\nReactElementFactory.Instance.registerElement(\n \"svc-image-question\",\n (props: QuestionAdornerComponentProps) => {\n return React.createElement(QuestionImageAdornerComponent, props);\n }\n);\n","import * as React from \"react\";\nimport { Base } from \"survey-core\";\nimport { QuestionRatingAdornerViewModel } from \"survey-creator-core\";\nimport { attachKey2click, ReactElementFactory, SvgIcon } from \"survey-react-ui\";\nimport { QuestionAdornerComponentProps } from \"./Question\";\nimport { CreatorModelElement } from \"../ModelElement\";\n\nexport class QuestionRatingAdornerComponent extends CreatorModelElement<QuestionAdornerComponentProps, any> {\n private modelValue: QuestionRatingAdornerViewModel;\n\n protected createModel(props: any): void {\n this.modelValue = this.createQuestionViewModel(props);\n }\n protected createQuestionViewModel(props: any): QuestionRatingAdornerViewModel {\n return new QuestionRatingAdornerViewModel(\n props.componentData,\n props.question as any,\n null\n );\n }\n protected getUpdatedModelProps(): string[] {\n return [\"question\", \"componentData\"];\n }\n public get ratingModel(): QuestionRatingAdornerViewModel {\n return this.model as QuestionRatingAdornerViewModel;\n }\n public get model(): QuestionRatingAdornerViewModel {\n return this.modelValue;\n }\n protected getStateElement(): Base {\n return this.model;\n }\n protected renderElement(): React.JSX.Element {\n const model = this.ratingModel;\n return (<>\n <div className=\"svc-rating-question-content\">\n <div className={model.controlsClassNames}>\n {model.allowRemove ? attachKey2click(<span\n role=\"button\"\n className={model.removeClassNames}\n aria-label={model.removeTooltip}\n onClick={() => model.removeItem(model)}\n >\n <SvgIcon size={\"auto\"} iconName={\"icon-remove_16x16\"} title={model.removeTooltip}></SvgIcon>\n </span>) : null}\n {model.allowAdd ? attachKey2click(<span\n role=\"button\"\n className={model.addClassNames}\n aria-label={model.addTooltip}\n onClick={() => model.addItem(model)}\n >\n <SvgIcon size={\"auto\"} iconName={\"icon-add_16x16\"} title={model.addTooltip}></SvgIcon>\n </span>) : null}\n </div>\n {this.props.element}\n </div>\n </>);\n }\n}\n\nReactElementFactory.Instance.registerElement(\n \"svc-rating-question\",\n (props: QuestionAdornerComponentProps) => {\n return React.createElement(QuestionRatingAdornerComponent, props);\n }\n);\nReactElementFactory.Instance.registerElement(\n \"svc-rating-question-content\",\n (props: QuestionAdornerComponentProps) => {\n return React.createElement(QuestionRatingAdornerComponent, props);\n }\n);\n","import {\n QuestionAdornerViewModel\n} from \"survey-creator-core\";\nimport * as React from \"react\";\nimport {\n QuestionAdornerComponent,\n QuestionAdornerComponentProps\n} from \"./Question\";\nimport { attachKey2click, ReactElementFactory, SvgIcon } from \"survey-react-ui\";\n\nexport class QuestionWidgetAdornerComponent extends QuestionAdornerComponent {\n protected createQuestionViewModel(props: any): QuestionAdornerViewModel {\n return new QuestionAdornerViewModel(\n props.componentData,\n props.question as any,\n null\n );\n }\n public get widgetModel(): QuestionAdornerViewModel {\n return this.model as QuestionAdornerViewModel;\n }\n protected renderElementContent(): React.JSX.Element {\n return (\n <div\n className={\"svc-widget__content\"}\n >\n {this.props.element}\n </div>\n );\n }\n}\n\nReactElementFactory.Instance.registerElement(\n \"svc-widget-question\",\n (props: QuestionAdornerComponentProps) => {\n return React.createElement(QuestionWidgetAdornerComponent, props);\n }\n);\n","import * as React from \"react\";\nimport { Base, Question } from \"survey-core\";\nimport {\n attachKey2click,\n ReactElementFactory\n} from \"survey-react-ui\";\nimport { CreatorModelElement } from \"../ModelElement\";\nimport { QuestionAdornerViewModel, toggleHovered } from \"survey-creator-core\";\nimport { ReactDragEvent, ReactMouseEvent } from \"../events\";\nimport { QuestionAdornerComponentProps } from \"./Question\";\n\nexport class CellQuestionAdornerComponent extends CreatorModelElement<\n QuestionAdornerComponentProps,\n any\n> {\n model: QuestionAdornerViewModel;\n protected createModel(props: any): void {\n this.model = new QuestionAdornerViewModel(\n props.componentData,\n props.question,\n null\n );\n }\n protected getStateElement(): Base {\n return this.model;\n }\n protected getUpdatedModelProps(): string[] {\n return [\"question\", \"componentData\"];\n }\n render(): React.JSX.Element {\n return (\n <React.Fragment>\n <div\n data-sv-drop-target-survey-element={this.model.element.name}\n className={\"svc-question__adorner\"}\n >\n <div className={\" svc-question__content--in-popup svc-question__content\"}>\n {this.props.element}\n </div>\n </div>\n </React.Fragment>\n );\n }\n}\n\nReactElementFactory.Instance.registerElement(\n \"svc-cell-question\",\n (props: QuestionAdornerComponentProps) => {\n return React.createElement(CellQuestionAdornerComponent, props);\n }\n);\n","import { QuestionAdornerViewModel, toggleHovered } from \"survey-creator-core\";\nimport * as React from \"react\";\nimport { ReactDragEvent, ReactMouseEvent } from \"../events\";\nimport { Base, ItemValue, QuestionSelectBase, SurveyModel } from \"survey-core\";\nimport { ReactElementFactory, ReactSurveyElementsWrapper } from \"survey-react-ui\";\nimport { QuestionAdornerComponentProps } from \"./Question\";\nimport { CreatorModelElement } from \"../ModelElement\";\nimport { attachKey2click } from \"survey-react-ui\";\n\nexport class CellQuestionDropdownAdornerComponent extends CreatorModelElement<\n QuestionAdornerComponentProps,\n any\n> {\n model: QuestionAdornerViewModel;\n protected createModel(props: any): void {\n this.model = new QuestionAdornerViewModel(\n props.componentData,\n props.question,\n null\n );\n }\n protected getUpdatedModelProps(): string[] {\n return [\"question\", \"componentData\"];\n }\n protected getStateElement(): Base {\n return this.model;\n }\n render(): React.JSX.Element {\n const question = this.props.question as QuestionSelectBase;\n const textStyle = (this.props.question as any).textStyle;\n return (\n <React.Fragment>\n <div\n data-sv-drop-target-survey-element={this.model.element.name}\n className={\"svc-question__adorner\"}\n >\n <div className={\" svc-question__content--in-popup svc-question__content\"}>\n {this.props.element}\n\n <div className=\"svc-question__dropdown-choices\">\n {question.visibleChoices.map(\n (item: ItemValue, index: number) => (\n <div\n className=\"svc-question__dropdown-choice\"\n key={`editable_choice_${index}`}\n >\n {ReactSurveyElementsWrapper.wrapItemValue(question.survey as SurveyModel,\n ReactElementFactory.Instance.createElement(\n \"survey-radiogroup-item\",\n {\n question: question,\n cssClasses: question.cssClasses,\n isDisplayMode: true,\n item: item,\n textStyle: textStyle,\n index: index,\n isChecked: question.value === item.value\n }\n ),\n question,\n item\n )}\n </div>\n )\n )}\n </div>\n </div>\n </div>\n </React.Fragment>\n );\n }\n}\n\nReactElementFactory.Instance.registerElement(\n \"svc-cell-dropdown-question\",\n (props: QuestionAdornerComponentProps) => {\n return React.createElement(CellQuestionDropdownAdornerComponent, props);\n }\n);\n","import * as React from \"react\";\nimport { Action, Base, IAction, PageModel, SurveyModel } from \"survey-core\";\nimport {\n attachKey2click,\n Popup,\n SurveyActionBar,\n ReactElementFactory,\n SurveyPage,\n SvgIcon,\n LoadingIndicatorComponent\n} from \"survey-react-ui\";\nimport { CreatorModelElement } from \"../ModelElement\";\nimport {\n SurveyCreatorModel,\n PageAdorner,\n SurveyHelper,\n toggleHovered\n} from \"survey-creator-core\";\nimport { ReactMouseEvent } from \"../events\";\n\ninterface ICreatorSurveyPageComponentProps {\n creator: SurveyCreatorModel;\n survey: SurveyModel;\n page: PageModel;\n isGhost: boolean;\n}\nconst PageElementContent = React.memo(({ page, survey, creator }: {\n page: PageModel,\n survey: SurveyModel,\n creator: SurveyCreatorModel,\n}) => {\n return <SurveyPage page={page} survey={survey} creator={creator} />;\n});\nPageElementContent.displayName = \"PageElementContent\";\n\nexport class CreatorSurveyPageComponent extends CreatorModelElement<\n ICreatorSurveyPageComponentProps,\n any\n> {\n private model: PageAdorner;\n private rootRef: React.RefObject<HTMLDivElement>;\n constructor(props: ICreatorSurveyPageComponentProps) {\n super(props);\n this.rootRef = React.createRef();\n }\n protected createModel(props: ICreatorSurveyPageComponentProps): void {\n if (this.model) {\n this.model.attachToUI(props.page, this.rootRef.current);\n }\n this.model = this.createPageAdorner(props.creator, props.page);\n this.model.isGhost = this.props.isGhost;\n }\n protected createPageAdorner(creator: SurveyCreatorModel, page: PageModel): PageAdorner {\n return new PageAdorner(creator, page);\n }\n shouldComponentUpdate(nextProps: any, nextState: any): boolean {\n const res = super.shouldComponentUpdate(nextProps, nextState);\n if (this.model) {\n this.model.isGhost = this.props.isGhost;\n }\n return res;\n }\n public componentDidUpdate(prevProps: any, prevState: any): void {\n super.componentDidUpdate(prevProps, prevState);\n }\n protected getUpdatedModelProps(): string[] {\n return [\"creator\", \"page\"];\n }\n protected getStateElement(): Base {\n return this.model;\n }\n componentDidMount() {\n super.componentDidMount();\n this.model.attachToUI(this.props.page, this.rootRef.current);\n this.model.isGhost = this.props.isGhost;\n }\n componentWillUnmount() {\n super.componentWillUnmount();\n this.model.detachFromUI();\n }\n protected canRender(): boolean {\n return super.canRender();\n }\n renderElement(): React.JSX.Element {\n if (!this.props.page) return null;\n return (\n attachKey2click(<div\n ref={this.rootRef}\n id={this.props.page.id}\n data-sv-drop-target-survey-page={this.model.dropTargetName}\n className={\"svc-page__content \" + this.model.css}\n onClick={(e) => {\n return this.model.select(this.model, new ReactMouseEvent(e));\n }}\n onDoubleClick={e => this.model.dblclick(e.nativeEvent)}\n onMouseLeave={(e) => this.model.hover(e.nativeEvent, e.currentTarget)}\n onMouseOver={(e) => this.model.hover(e.nativeEvent, e.currentTarget)}\n >\n <div className=\"svc-question__drop-indicator svc-question__drop-indicator--top\"></div>\n <div className=\"svc-question__drop-indicator svc-question__drop-indicator--bottom\"></div>\n {this.renderContent()}\n {this.renderPlaceholder()}\n {this.renderHeader()}\n {this.renderFooter()}\n </div>)\n );\n }\n protected renderPlaceholder(): React.JSX.Element {\n if (!this.model.showPlaceholder) return null;\n return (\n <div className=\"svc-page__placeholder_frame\">\n <div className=\"svc-panel__placeholder_frame\">\n <div className=\"svc-panel__placeholder\">{this.model.placeholderText}</div>\n </div>\n </div>\n );\n }\n protected renderContent(): React.JSX.Element {\n if (!this.model.needRenderContent) {\n return <div className={\"svc-page__loading-content\"}><LoadingIndicatorComponent></LoadingIndicatorComponent></div>;\n }\n return (\n <PageElementContent\n page={this.props.page}\n survey={this.pr