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 lines 1.75 MB
{"version":3,"file":"survey-react-ui.mjs","sources":["../../src/element-factory.tsx","../../src/reactsurveymodel.tsx","../../src/reactquestion_element.tsx","../../src/element.tsx","../../src/row.tsx","../../src/panel-base.tsx","../../src/components/svg-icon/svg-icon.tsx","../../src/components/action-bar/action-bar-separator.tsx","../../src/components/action-bar/action-bar-item.tsx","../../src/components/popup/popup.tsx","../../src/components/action-bar/action-bar-item-dropdown.tsx","../../src/components/action-bar/action-bar.tsx","../../src/components/title/title-content.tsx","../../src/components/title/title-actions.tsx","../../src/components/title/title-element.tsx","../../src/reactquestion_factory.tsx","../../src/components/character-counter.tsx","../../src/components/text-area.tsx","../../src/reactquestion_comment.tsx","../../src/custom-widget.tsx","../../src/element-header.tsx","../../src/reactquestion.tsx","../../src/page.tsx","../../src/components/survey-header/survey-header.tsx","../../src/components/brand-info.tsx","../../src/components/notifier.tsx","../../src/components/components-container.tsx","../../src/svgbundle.tsx","../../src/components/popup/popup-modal.tsx","../../../survey-core/build/fesm/icons/iconsV1.mjs","../../../survey-core/build/fesm/icons/iconsV2.mjs","../../src/components/scroll.tsx","../../src/reactSurvey.tsx","../../src/reactSurveyNavigationBase.tsx","../../src/reacttimerpanel.tsx","../../src/panel.tsx","../../src/flow-panel.tsx","../../src/reactquestion_checkbox.tsx","../../src/reactquestion_ranking.tsx","../../src/components/rating/rating-item.tsx","../../src/components/rating/rating-item-star.tsx","../../src/components/rating/rating-item-smiley.tsx","../../src/components/rating/rating-dropdown-item.tsx","../../src/tagbox-filter.tsx","../../src/dropdown-item.tsx","../../src/dropdown-base.tsx","../../src/reactquestion_dropdown.tsx","../../src/tagbox-item.tsx","../../src/reactquestion_tagbox.tsx","../../src/dropdown-select.tsx","../../src/reactquestion_matrix.tsx","../../src/reactquestion_html.tsx","../../src/components/loading-indicator.tsx","../../src/components/file/file-choose-button.tsx","../../src/reactquestion_file.tsx","../../src/components/file/file-item.tsx","../../src/components/file/file-page.tsx","../../src/components/file/file-preview.tsx","../../src/reactquestion_multipletext.tsx","../../src/reactquestion_radiogroup.tsx","../../src/reactquestion_text.tsx","../../src/boolean.tsx","../../src/boolean-checkbox.tsx","../../src/boolean-radio.tsx","../../src/reactquestion_empty.tsx","../../src/components/matrix/row.tsx","../../src/components/matrix-actions/drag-drop-icon/drag-drop-icon.tsx","../../src/reactquestion_matrixdropdownbase.tsx","../../src/reactquestion_matrixdropdown.tsx","../../src/reactquestion_matrixdynamic.tsx","../../src/components/paneldynamic-actions/paneldynamic-add-btn.tsx","../../src/components/paneldynamic-actions/paneldynamic-next-btn.tsx","../../src/components/paneldynamic-actions/paneldynamic-prev-btn.tsx","../../src/components/paneldynamic-actions/paneldynamic-progress-text.tsx","../../src/reactquestion_paneldynamic.tsx","../../src/progress.tsx","../../src/progressButtons.tsx","../../src/components/list/list-item.tsx","../../src/components/list/list.tsx","../../src/progressToc.tsx","../../src/reactquestion_rating.tsx","../../src/rating-dropdown.tsx","../../src/reactquestion_expression.tsx","../../src/react-popup-survey.tsx","../../src/imagepicker.tsx","../../src/image.tsx","../../src/signaturepad.tsx","../../src/reactquestion_buttongroup.tsx","../../src/reactquestion_custom.tsx","../../src/components/list/list-item-content.tsx","../../src/components/list/list-item-group.tsx","../../src/components/survey-header/logo-image.tsx","../../src/components/matrix-actions/remove-button/remove-button.tsx","../../src/components/matrix-actions/detail-button/detail-button.tsx","../../src/components/paneldynamic-actions/paneldynamic-remove-btn.tsx","../../src/components/survey-actions/survey-nav-button.tsx","../../src/string-viewer.tsx","../../src/components/question-error.tsx","../../src/components/skeleton.tsx","../../src/components/header.tsx","../../src/string-editor.tsx","../../entries/index.ts"],"sourcesContent":["import { HashTable } from \"survey-core\";\n\nexport class ReactElementFactory {\n public static Instance: ReactElementFactory = new ReactElementFactory();\n private creatorHash: HashTable<(name: string) => React.JSX.Element> = {};\n\n public registerElement(\n elementType: string,\n elementCreator: (props: any) => React.JSX.Element\n ) {\n this.creatorHash[elementType] = elementCreator;\n }\n public getAllTypes(): Array<string> {\n var result = new Array<string>();\n for (var key in this.creatorHash) {\n result.push(key);\n }\n return result.sort();\n }\n public isElementRegistered(elementType: string) {\n return !!this.creatorHash[elementType];\n }\n public createElement(elementType: string, params: any): React.JSX.Element | any {\n var creator = this.creatorHash[elementType];\n if (creator == null) return null;\n return creator(params);\n }\n}\n","import { SurveyModel, QuestionMatrixDropdownRenderedCell, SurveyElement, QuestionRowModel, ItemValue, QuestionSelectBase } from \"survey-core\";\nimport { ReactElementFactory } from \"./element-factory\";\n\nexport class ReactSurveyElementsWrapper {\n public static wrapRow(survey: SurveyModel, element: React.JSX.Element, row: QuestionRowModel): React.JSX.Element {\n const componentName = survey.getRowWrapperComponentName(row);\n const componentData = survey.getRowWrapperComponentData(row);\n return ReactElementFactory.Instance.createElement(componentName, {\n element,\n row,\n componentData,\n });\n }\n public static wrapElement(survey: SurveyModel, element: React.JSX.Element, question: SurveyElement): React.JSX.Element {\n const componentName = survey.getElementWrapperComponentName(question);\n const componentData = survey.getElementWrapperComponentData(question);\n return ReactElementFactory.Instance.createElement(componentName, {\n element,\n question,\n componentData,\n });\n }\n public static wrapQuestionContent(survey: SurveyModel, element: React.JSX.Element, question: SurveyElement): React.JSX.Element {\n const componentName = survey.getQuestionContentWrapperComponentName(question);\n const componentData = survey.getElementWrapperComponentData(question);\n return ReactElementFactory.Instance.createElement(componentName, {\n element,\n question,\n componentData,\n });\n }\n public static wrapItemValue(survey: SurveyModel, element: React.JSX.Element, question: QuestionSelectBase, item: ItemValue): React.JSX.Element {\n const componentName = survey.getItemValueWrapperComponentName(item, question);\n const componentData = survey.getItemValueWrapperComponentData(item, question);\n return ReactElementFactory.Instance.createElement(componentName, {\n key: element?.key,\n element,\n question,\n item,\n componentData,\n });\n }\n public static wrapMatrixCell(survey: SurveyModel, element: React.JSX.Element, cell: QuestionMatrixDropdownRenderedCell, reason: string = \"cell\"): React.JSX.Element {\n const componentName = survey.getElementWrapperComponentName(cell, reason);\n const componentData = survey.getElementWrapperComponentData(cell, reason);\n return ReactElementFactory.Instance.createElement(componentName, {\n element,\n cell,\n componentData,\n });\n }\n}\n\nSurveyModel.platform = \"react\";\n","import * as React from \"react\";\nimport { Base, ArrayChanges, SurveyModel, Helpers, PanelModel, LocalizableString, Question } from \"survey-core\";\nimport { ISurveyCreator } from \"./reactquestion\";\nimport { ReactElementFactory } from \"./element-factory\";\nimport { ReactSurveyElementsWrapper } from \"./reactsurveymodel\";\n\nexport class SurveyElementBase<P, S> extends React.Component<P, S> {\n public static renderLocString(\n locStr: LocalizableString,\n style: any = null,\n key?: string\n ): React.JSX.Element {\n return ReactElementFactory.Instance.createElement(locStr.renderAs, {\n locStr: locStr.renderAsData,\n style: style,\n key: key,\n });\n }\n public static renderQuestionDescription(question: Question | PanelModel): React.JSX.Element {\n var descriptionText = SurveyElementBase.renderLocString(question.locDescription);\n return <div style={question.hasDescription ? undefined : { display: \"none\" }} id={question.ariaDescriptionId} className={question.cssDescription}>{descriptionText}</div>;\n }\n private changedStatePropNameValue: string | undefined;\n constructor(props: any) {\n super(props);\n }\n componentDidMount() {\n this.makeBaseElementsReact();\n }\n componentWillUnmount() {\n this.unMakeBaseElementsReact();\n this.disableStateElementsRerenderEvent(this.getStateElements());\n }\n componentDidUpdate(prevProps: any, prevState: any) {\n this.makeBaseElementsReact();\n const stateElements = this.getStateElements();\n this.disableStateElementsRerenderEvent((this.prevStateElements ?? []).filter(el => !stateElements.find(stateElement => stateElement == el)));\n this.prevStateElements = [];\n this.getStateElements().forEach((el) => {\n el.afterRerender();\n });\n }\n private _allowComponentUpdate = true;\n protected allowComponentUpdate() {\n this._allowComponentUpdate = true;\n this.forceUpdate();\n }\n protected denyComponentUpdate() {\n this._allowComponentUpdate = false;\n }\n private prevStateElements: Array<Base> = [];\n shouldComponentUpdate(nextProps: any, nextState: any): boolean {\n if (this._allowComponentUpdate) {\n this.unMakeBaseElementsReact();\n this.prevStateElements = this.getStateElements();\n }\n return this._allowComponentUpdate;\n }\n render(): React.JSX.Element | null {\n if (!this.canRender()) {\n return null;\n }\n\n this.startEndRendering(1);\n var res = this.renderElement();\n this.startEndRendering(-1);\n\n if (!!res) {\n res = this.wrapElement(res);\n }\n\n this.changedStatePropNameValue = undefined;\n return res;\n }\n protected wrapElement(element: React.JSX.Element): React.JSX.Element {\n return element;\n }\n protected get isRendering(): boolean {\n var stateEls: Array<any> = this.getRenderedElements();\n for (let stateEl of stateEls) {\n if (stateEl.reactRendering > 0) return true;\n }\n return false;\n }\n protected getRenderedElements(): Base[] {\n return this.getStateElements();\n }\n private startEndRendering(val: number) {\n var stateEls: Array<any> = this.getRenderedElements();\n for (let stateEl of stateEls) {\n if (!stateEl.reactRendering) stateEl.reactRendering = 0;\n stateEl.reactRendering += val;\n }\n }\n protected canRender(): boolean {\n return true;\n }\n protected renderElement(): React.JSX.Element | null {\n return null;\n }\n protected get changedStatePropName(): string | undefined {\n return this.changedStatePropNameValue;\n }\n private makeBaseElementsReact() {\n var els = this.getStateElements();\n for (var i = 0; i < els.length; i++) {\n els[i].enableOnElementRerenderedEvent();\n this.makeBaseElementReact(els[i]);\n }\n }\n private unMakeBaseElementsReact() {\n var els = this.getStateElements();\n this.unMakeBaseElementsReactive(els);\n }\n private unMakeBaseElementsReactive(els: Array<Base>) {\n for (var i = 0; i < els.length; i++) {\n this.unMakeBaseElementReact(els[i]);\n }\n }\n protected disableStateElementsRerenderEvent(els: Array<Base>): void {\n els.forEach(el => {\n el.disableOnElementRerenderedEvent();\n });\n }\n protected getStateElements(): Array<Base> {\n var el = this.getStateElement();\n return !!el ? [el] : [];\n }\n protected getStateElement(): Base | null {\n return null;\n }\n protected get isDisplayMode(): boolean {\n const props: any = this.props;\n return props.isDisplayMode || false;\n }\n protected renderLocString(\n locStr: LocalizableString,\n style: any = null,\n key?: string\n ): React.JSX.Element {\n return SurveyElementBase.renderLocString(locStr, style, key);\n }\n private canMakeReact(stateElement: Base): boolean {\n return !!stateElement && !!stateElement.iteratePropertiesHash;\n }\n private propertyValueChangedHandler = (hash: any, key: string, val: any) => {\n if (hash[key] !== val) {\n hash[key] = val;\n if (!this.canUsePropInState(key)) return;\n if (this.isRendering) return;\n this.changedStatePropNameValue = key;\n this.setState((state: any) => {\n var newState: { [index: string]: any } = {};\n newState[key] = val;\n return newState as S;\n });\n }\n };\n protected isCurrentStateElement(stateElement: Base) {\n return !!stateElement && !!stateElement.setPropertyValueCoreHandler && stateElement.setPropertyValueCoreHandler === this.propertyValueChangedHandler;\n }\n private makeBaseElementReact(stateElement: Base) {\n if (!this.canMakeReact(stateElement)) return;\n stateElement.iteratePropertiesHash((hash, key) => {\n if (!this.canUsePropInState(key)) return;\n var val: any = hash[key];\n if (Array.isArray(val)) {\n var val: any = val;\n val[\"onArrayChanged\"] = (arrayChanges: ArrayChanges) => {\n if (this.isRendering) return;\n this.changedStatePropNameValue = key;\n this.setState((state: any) => {\n var newState: { [index: string]: any } = {};\n newState[key] = val;\n return newState as S;\n });\n };\n }\n });\n stateElement.setPropertyValueCoreHandler = this.propertyValueChangedHandler;\n }\n protected canUsePropInState(key: string): boolean {\n return true;\n }\n private unMakeBaseElementReact(stateElement: Base) {\n if (!this.canMakeReact(stateElement)) return;\n if (!this.isCurrentStateElement(stateElement)) {\n // eslint-disable-next-line no-console\n // console.warn(\"Looks like the component is bound to another survey element. It is not supported and can lead to issues.\");\n // return;\n }\n stateElement.setPropertyValueCoreHandler = undefined as any;\n stateElement.iteratePropertiesHash((hash, key) => {\n var val: any = hash[key];\n if (Array.isArray(val)) {\n var val: any = val;\n val[\"onArrayChanged\"] = () => { };\n }\n });\n }\n}\n\nexport class ReactSurveyElement extends SurveyElementBase<any, any> {\n constructor(props: any) {\n super(props);\n }\n protected get cssClasses(): any {\n return this.props.cssClasses;\n }\n}\n\nexport class SurveyQuestionElementBase extends SurveyElementBase<any, any> {\n control: HTMLElement;\n content: HTMLElement;\n constructor(props: any) {\n super(props);\n }\n componentDidUpdate(prevProps: any, prevState: any) {\n super.componentDidUpdate(prevProps, prevState);\n this.updateDomElement();\n }\n componentDidMount() {\n super.componentDidMount();\n this.updateDomElement();\n }\n componentWillUnmount() {\n super.componentWillUnmount();\n if (!!this.questionBase) {\n const contentElement: HTMLElement = this.content || this.control;\n this.questionBase.beforeDestroyQuestionElement(contentElement);\n if (!!contentElement) {\n contentElement.removeAttribute(\"data-rendered\");\n }\n }\n }\n protected updateDomElement() {\n const contentElement = this.content || this.control;\n if (!!contentElement) {\n if (contentElement.getAttribute(\"data-rendered\") !== \"r\") {\n contentElement.setAttribute(\"data-rendered\", \"r\");\n this.questionBase.afterRenderQuestionElement(contentElement);\n }\n }\n }\n protected get questionBase(): Question {\n return this.props.question;\n }\n protected getRenderedElements(): Base[] {\n return [this.questionBase];\n }\n protected get creator(): ISurveyCreator {\n return this.props.creator;\n }\n protected canRender(): boolean {\n return !!this.questionBase && !!this.creator;\n }\n public shouldComponentUpdate(nextProps: any, nextState: any): boolean {\n if (!super.shouldComponentUpdate(nextProps, nextState)) return false;\n\n return (\n !this.questionBase.customWidget ||\n !!this.questionBase.customWidgetData.isNeedRender ||\n !!this.questionBase.customWidget.widgetJson.isDefaultRender ||\n !!this.questionBase.customWidget.widgetJson.render\n );\n }\n protected get isDisplayMode(): boolean {\n const props: any = this.props;\n return (\n props.isDisplayMode ||\n (!!this.questionBase && this.questionBase.isInputReadOnly) || false\n );\n }\n protected wrapCell(\n cell: any,\n element: React.JSX.Element,\n reason: string\n ): React.JSX.Element {\n if (!reason) {\n return element;\n }\n const survey: SurveyModel = this.questionBase\n .survey as SurveyModel;\n let wrapper: React.JSX.Element | null = null;\n if (survey) {\n wrapper = ReactSurveyElementsWrapper.wrapMatrixCell(survey, element, cell, reason);\n }\n return wrapper ?? element;\n }\n public setControl(element: HTMLElement | null): void {\n if (!!element) {\n this.control = element;\n }\n }\n public setContent(element: HTMLElement | null): void {\n if (!!element) {\n this.content = element;\n }\n }\n}\n\nexport class SurveyQuestionUncontrolledElement<\n T extends Question\n> extends SurveyQuestionElementBase {\n constructor(props: any) {\n super(props);\n this.updateValueOnEvent = this.updateValueOnEvent.bind(this);\n }\n protected get question(): T {\n return this.questionBase as T;\n }\n updateValueOnEvent = (event: any) => {\n if (\n !Helpers.isTwoValueEquals(this.questionBase.value, event.target.value, false, true, false)\n ) {\n this.setValueCore(event.target.value);\n }\n };\n protected setValueCore(newValue: any) {\n this.questionBase.value = newValue;\n }\n protected getValueCore(): any {\n return this.questionBase.value;\n }\n protected updateDomElement() {\n if (!!this.control) {\n const control: any = this.control;\n const newValue = this.getValueCore();\n if (!Helpers.isTwoValueEquals(newValue, control.value, false, true, false)) {\n control.value = this.getValue(newValue);\n }\n }\n super.updateDomElement();\n }\n private getValue(val: any): any {\n if (Helpers.isValueEmpty(val)) return \"\";\n return val;\n }\n}\n","import * as React from \"react\";\nimport { ISurveyCreator } from \"./reactquestion\";\nimport { SurveyModel, Question, QuestionRowModel, IElement, Base, PanelModel } from \"survey-core\";\nimport { SurveyElementBase } from \"./reactquestion_element\";\nimport { ReactElementFactory } from \"./element-factory\";\nimport { ReactSurveyElementsWrapper } from \"./reactsurveymodel\";\n\nexport class SurveyRowElement extends SurveyElementBase<any, any> {\n private rootRef: React.RefObject<HTMLDivElement>;\n constructor(props: any) {\n super(props);\n (this.element as Question).cssClasses;\n this.rootRef = React.createRef();\n }\n protected getStateElement(): any {\n return this.element;\n }\n private get element(): PanelModel | Question {\n return this.props.element as any;\n }\n private get index(): number {\n return this.props.index;\n }\n private get row(): QuestionRowModel {\n return this.props.row;\n }\n private get survey(): SurveyModel {\n return this.props.survey;\n }\n private get creator(): ISurveyCreator {\n return this.props.creator;\n }\n protected get css(): any {\n return this.props.css;\n }\n\n componentDidMount(): void {\n super.componentDidMount();\n if (this.rootRef.current) {\n (this.element).setWrapperElement(this.rootRef.current);\n }\n }\n\n componentWillUnmount(): void {\n super.componentWillUnmount();\n this.element.setWrapperElement(undefined);\n }\n\n public shouldComponentUpdate(nextProps: any, nextState: any): boolean {\n if (!super.shouldComponentUpdate(nextProps, nextState)) return false;\n if (nextProps.element !== this.element) {\n if (nextProps.element) {\n nextProps.element.setWrapperElement(this.rootRef.current);\n }\n if (this.element) {\n this.element.setWrapperElement(undefined);\n }\n }\n\n (this.element as Question).cssClasses;\n return true;\n }\n\n protected renderElement(): React.JSX.Element {\n const element = this.element;\n const innerElement = this.createElement(element, this.index);\n const css = (element as Question).cssClassesValue;\n const focusIn = () => {\n const el: any = element;\n if (el && el.isQuestion) {\n el.focusIn();\n }\n };\n return (\n <div\n className={css.questionWrapper}\n style={(element as any).rootStyle}\n data-key={element.name + this.index}\n onFocus={focusIn}\n ref={this.rootRef}\n >\n {innerElement}\n </div>\n );\n }\n\n protected createElement(element: IElement, elementIndex?: number): React.JSX.Element {\n if (!this.row.isNeedRender) {\n return ReactElementFactory.Instance.createElement(element.skeletonComponentName, { element: element, css: this.css, });\n }\n let elementType = (element as any).getTemplate();\n if (!ReactElementFactory.Instance.isElementRegistered(elementType)) {\n elementType = \"question\";\n }\n return ReactElementFactory.Instance.createElement(elementType, {\n element: element,\n creator: this.creator,\n survey: this.survey,\n css: this.css,\n });\n }\n}\n","import * as React from \"react\";\nimport { ISurveyCreator } from \"./reactquestion\";\nimport { SurveyModel, Question, QuestionRowModel, IElement, Base, PanelModel } from \"survey-core\";\nimport { SurveyElementBase } from \"./reactquestion_element\";\nimport { SurveyRowElement } from \"./element\";\nimport { ReactElementFactory } from \"./element-factory\";\nimport { ReactSurveyElementsWrapper } from \"./reactsurveymodel\";\n\nexport class SurveyRow extends SurveyElementBase<any, any> {\n private rootRef: React.RefObject<HTMLDivElement>;\n constructor(props: any) {\n super(props);\n this.rootRef = React.createRef();\n this.recalculateCss();\n }\n private recalculateCss() {\n this.row.visibleElements.map(element => (element as Question).cssClasses);\n }\n protected getStateElement(): Base {\n return this.row;\n }\n private get row(): QuestionRowModel {\n return this.props.row;\n }\n private get survey(): SurveyModel {\n return this.props.survey;\n }\n private get creator(): ISurveyCreator {\n return this.props.creator;\n }\n protected get css(): any {\n return this.props.css;\n }\n protected canRender(): boolean {\n return !!this.row && !!this.survey && !!this.creator;\n }\n protected renderElementContent(): React.JSX.Element {\n const elements = this.row.visibleElements.map((element, elementIndex) => {\n return (\n <SurveyRowElement\n element={element}\n index={elementIndex}\n row={this.row}\n survey={this.survey}\n creator={this.creator}\n css={this.css}\n key={(element as PanelModel | Question).id}\n >\n </SurveyRowElement>\n );\n });\n\n return (\n <div ref={this.rootRef} className={this.row.getRowCss()} >\n {elements}\n </div>\n );\n }\n protected renderElement(): React.JSX.Element {\n const survey: SurveyModel = this.survey as SurveyModel;\n const content = this.renderElementContent();\n const wrapper = ReactSurveyElementsWrapper.wrapRow(survey, content, this.row);\n return wrapper || content;\n }\n componentDidMount() {\n super.componentDidMount();\n var el = this.rootRef.current;\n if (this.rootRef.current) {\n this.row.setRootElement(this.rootRef.current);\n }\n if (!!el && !this.row.isNeedRender) {\n var rowContainerDiv = el;\n setTimeout(() => {\n this.row.startLazyRendering(rowContainerDiv);\n }, 10);\n }\n }\n public shouldComponentUpdate(nextProps: any, nextState: any): boolean {\n if (!super.shouldComponentUpdate(nextProps, nextState)) return false;\n if (nextProps.row !== this.row) {\n nextProps.row.isNeedRender = this.row.isNeedRender;\n nextProps.row.setRootElement(this.rootRef.current);\n this.row.setRootElement(undefined);\n this.stopLazyRendering();\n }\n this.recalculateCss();\n return true;\n }\n private stopLazyRendering() {\n this.row.stopLazyRendering();\n this.row.isNeedRender = !this.row.isLazyRendering();\n }\n componentWillUnmount() {\n super.componentWillUnmount();\n if (this.isCurrentStateElement(this.getStateElement())) {\n this.row.setRootElement(undefined);\n this.stopLazyRendering();\n }\n }\n\n protected createElement(element: IElement, elementIndex?: number): React.JSX.Element {\n const index = elementIndex ? \"-\" + elementIndex : 0;\n var elementType = element.getType();\n if (!ReactElementFactory.Instance.isElementRegistered(elementType)) {\n elementType = \"question\";\n }\n return ReactElementFactory.Instance.createElement(elementType, {\n key: element.name + index,\n element: element,\n creator: this.creator,\n survey: this.survey,\n css: this.css,\n });\n }\n}\n","import * as React from \"react\";\nimport { ISurveyCreator } from \"./reactquestion\";\nimport { Base, SurveyModel, QuestionRowModel, PanelModel, PanelModelBase } from \"survey-core\";\nimport { SurveyElementBase } from \"./reactquestion_element\";\nimport { SurveyRow } from \"./row\";\n\nexport class SurveyPanelBase extends SurveyElementBase<any, any> {\n protected rootRef: React.RefObject<HTMLDivElement>;\n constructor(props: any) {\n super(props);\n this.rootRef = React.createRef();\n }\n protected getStateElement(): Base {\n return this.panelBase;\n }\n protected canUsePropInState(key: string): boolean {\n return key !== \"elements\" && super.canUsePropInState(key);\n }\n protected get survey(): SurveyModel | null {\n return this.getSurvey();\n }\n protected get creator(): ISurveyCreator {\n return this.props.creator;\n }\n protected get css(): any {\n return this.getCss();\n }\n public get panelBase(): PanelModelBase {\n return this.getPanelBase();\n }\n protected getPanelBase(): PanelModelBase {\n return this.props.element || this.props.question;\n }\n protected getSurvey(): SurveyModel | null {\n return (\n this.props.survey || (!!this.panelBase ? this.panelBase.survey : null)\n );\n }\n protected getCss(): any {\n return this.props.css;\n }\n componentDidMount() {\n super.componentDidMount();\n this.doAfterRender();\n }\n componentWillUnmount() {\n super.componentWillUnmount();\n var el = this.rootRef.current;\n if (!!el) {\n el.removeAttribute(\"data-rendered\");\n }\n }\n componentDidUpdate(prevProps: any, prevState: any) {\n super.componentDidUpdate(prevProps, prevState);\n if (\n !!prevProps.page &&\n !!this.survey &&\n !!this.survey.activePage &&\n prevProps.page.id === this.survey.activePage.id\n )\n return;\n this.doAfterRender();\n }\n private doAfterRender() {\n var el = this.rootRef.current;\n if (el && this.survey) {\n if (this.panelBase.isPanel) {\n this.panelBase.afterRender(el);\n } else {\n this.survey.afterRenderPage(el);\n }\n }\n }\n\n protected getIsVisible() {\n return this.panelBase.isVisible;\n }\n\n protected canRender(): boolean {\n return (\n super.canRender() && !!this.survey && !!this.panelBase && !!this.panelBase.survey && this.getIsVisible()\n );\n }\n protected renderRows(css: any): Array<React.JSX.Element> {\n return this.panelBase.visibleRows.map((row) => this.createRow(row, css));\n }\n protected createRow(row: QuestionRowModel, css: any): React.JSX.Element {\n return (\n <SurveyRow\n key={row.id}\n row={row}\n survey={this.survey}\n creator={this.creator}\n css={css}\n />\n );\n }\n}\n","import * as React from \"react\";\nimport { ReactElementFactory } from \"../../element-factory\";\nimport { createSvg } from \"survey-core\";\n\nexport class SvgIcon extends React.Component<any, any> {\n private svgIconRef: any;\n constructor(props: any) {\n super(props);\n this.svgIconRef = React.createRef();\n }\n\n updateSvg() {\n if (this.props.iconName)\n createSvg(\n this.props.size,\n this.props.width,\n this.props.height,\n this.props.iconName,\n this.svgIconRef.current,\n this.props.title,\n );\n }\n componentDidUpdate() {\n this.updateSvg();\n }\n render() {\n let className = \"sv-svg-icon\";\n if (this.props.className) {\n className += \" \" + this.props.className;\n }\n return (\n this.props.iconName ?\n <svg className={className} style={this.props.style} onClick={this.props.onClick} ref={this.svgIconRef} role=\"presentation\"><use></use></svg>\n : null\n );\n }\n componentDidMount() {\n this.updateSvg();\n }\n}\n\nReactElementFactory.Instance.registerElement(\"sv-svg-icon\", (props) => {\n return React.createElement(SvgIcon, props);\n});\n","import * as React from \"react\";\nimport { ReactElementFactory } from \"../../element-factory\";\n\nexport class SurveyActionBarSeparator extends React.Component<any, any> {\n constructor(props: any) {\n super(props);\n }\n render() {\n var className = `sv-action-bar-separator ${this.props.cssClasses}`;\n return <div className={className}></div>;\n }\n}\nReactElementFactory.Instance.registerElement(\n \"sv-action-bar-separator\",\n (props) => {\n return React.createElement(SurveyActionBarSeparator, props);\n }\n);\n","import * as React from \"react\";\r\nimport * as ReactDOM from \"react-dom\";\r\nimport { Base, Action } from \"survey-core\";\r\nimport { ReactElementFactory } from \"../../element-factory\";\r\nimport { SurveyElementBase } from \"../../reactquestion_element\";\r\nimport { attachKey2click } from \"../../reactSurvey\";\r\nimport { SvgIcon } from \"../svg-icon/svg-icon\";\r\nimport { SurveyActionBarSeparator } from \"./action-bar-separator\";\r\n\r\ninterface IActionBarItemProps {\r\n item: Action;\r\n}\r\n\r\nexport class SurveyAction extends SurveyElementBase<IActionBarItemProps, any> {\r\n private ref: React.RefObject<any>;\r\n constructor(props: any) {\r\n super(props);\r\n this.ref = React.createRef();\r\n }\r\n get item() {\r\n return this.props.item;\r\n }\r\n protected getStateElement(): Base {\r\n return this.item;\r\n }\r\n\r\n renderElement() {\r\n //refactor\r\n const itemClass = this.item.getActionRootCss();\r\n const separator = this.item.needSeparator ? (\r\n <SurveyActionBarSeparator></SurveyActionBarSeparator>\r\n ) : null;\r\n\r\n const itemComponent = ReactElementFactory.Instance.createElement(\r\n this.item.component || \"sv-action-bar-item\",\r\n {\r\n item: this.item,\r\n }\r\n );\r\n return (\r\n <div className={itemClass} id={this.item.id} ref={this.ref}>\r\n <div className=\"sv-action__content\">\r\n {separator}\r\n {itemComponent}\r\n </div>\r\n </div>\r\n );\r\n }\r\n componentWillUnmount(): void {\r\n super.componentWillUnmount();\r\n this.item.updateModeCallback = undefined;\r\n }\r\n componentDidMount(): void {\r\n super.componentDidMount();\r\n this.item.updateModeCallback = (mode, callback) => {\r\n queueMicrotask(() => {\r\n if ((ReactDOM as any)[\"flushSync\"]) {\r\n (ReactDOM as any)[\"flushSync\"](() => {\r\n this.item.mode = mode;\r\n });\r\n } else {\r\n this.item.mode = mode;\r\n }\r\n queueMicrotask(() => {\r\n callback(mode, this.ref.current);\r\n });\r\n });\r\n };\r\n this.item.afterRender();\r\n }\r\n}\r\n\r\nexport class SurveyActionBarItem extends SurveyElementBase<\r\n IActionBarItemProps,\r\n any\r\n> {\r\n get item(): Action {\r\n return this.props.item;\r\n }\r\n protected getStateElement(): Base {\r\n return this.item;\r\n }\r\n\r\n renderElement() {\r\n return <>{this.renderInnerButton()}</>;\r\n }\r\n\r\n renderText() {\r\n if (!this.item.hasTitle) return null;\r\n const titleClass = this.item.getActionBarItemTitleCss();\r\n return <span className={titleClass}>{this.item.title}</span>;\r\n }\r\n\r\n renderButtonContent() {\r\n const text = this.renderText();\r\n const svgIcon = !!this.item.iconName ? (\r\n <SvgIcon\r\n className={this.item.cssClasses.itemIcon}\r\n size={this.item.iconSize}\r\n iconName={this.item.iconName}\r\n title={this.item.tooltip || this.item.title}\r\n ></SvgIcon>\r\n ) : null;\r\n return (\r\n <>\r\n {svgIcon}\r\n {text}\r\n </>\r\n );\r\n }\r\n\r\n renderInnerButton() {\r\n const className = this.item.getActionBarItemCss();\r\n const title = this.item.tooltip || this.item.title;\r\n const buttonContent = this.renderButtonContent();\r\n const tabIndex = this.item.disableTabStop ? -1 : undefined;\r\n const button = attachKey2click(\r\n <button\r\n className={className}\r\n type=\"button\"\r\n disabled={this.item.disabled}\r\n onMouseDown={(args) => this.item.doMouseDown(args)}\r\n onFocus={(args) => this.item.doFocus(args)}\r\n onClick={(args) => this.item.doAction(args)}\r\n title={title}\r\n tabIndex={tabIndex}\r\n aria-checked={this.item.ariaChecked}\r\n aria-expanded={this.item.ariaExpanded}\r\n role={this.item.ariaRole}\r\n >\r\n {buttonContent}\r\n </button>, this.item, { processEsc: false });\r\n\r\n return button;\r\n }\r\n}\r\n\r\nReactElementFactory.Instance.registerElement(\"sv-action-bar-item\", (props) => {\r\n return React.createElement(SurveyActionBarItem, props);\r\n});\r\n","import * as React from \"react\";\nimport { Base, PopupModel, PopupBaseViewModel, PopupDropdownViewModel, createPopupViewModel, CssClassBuilder } from \"survey-core\";\nimport { ReactElementFactory } from \"../../element-factory\";\nimport { SurveyElementBase } from \"../../reactquestion_element\";\nimport { SurveyActionBar } from \"../action-bar/action-bar\";\n\ninterface IPopupProps {\n model: PopupModel;\n}\n\nexport class Popup extends SurveyElementBase<IPopupProps, any> {\n private popup: PopupBaseViewModel;\n private containerRef: React.RefObject<HTMLDivElement>;\n constructor(props: IPopupProps) {\n super(props);\n this.containerRef = React.createRef();\n this.createModel();\n }\n get model(): PopupModel {\n return this.props.model;\n }\n protected getStateElement(): Base {\n return this.model;\n }\n private createModel(): void {\n this.popup = createPopupViewModel(this.props.model);\n }\n private setTargetElement(): void {\n const container = this.containerRef.current as HTMLElement;\n this.popup.setComponentElement(container);\n }\n componentDidMount(): void {\n super.componentDidMount();\n this.setTargetElement();\n }\n componentDidUpdate(prevProps: any, prevState: any) {\n super.componentDidUpdate(prevProps, prevState);\n this.setTargetElement();\n }\n componentWillUnmount(): void {\n super.componentWillUnmount();\n this.popup.resetComponentElement();\n }\n shouldComponentUpdate(nextProps: IPopupProps, nextState: any) {\n if (!super.shouldComponentUpdate(nextProps, nextState)) return false;\n const isNeedUpdate = nextProps.model !== this.popup.model;\n if (isNeedUpdate) {\n this.popup?.dispose();\n this.createModel();\n }\n return isNeedUpdate;\n }\n render(): React.JSX.Element {\n this.popup.model = this.model;\n let popupContainer;\n if (this.model.isModal) {\n popupContainer = <PopupContainer model={this.popup}></PopupContainer>;\n } else {\n popupContainer = <PopupDropdownContainer model={this.popup}></PopupDropdownContainer>;\n }\n return <div ref={this.containerRef}>{popupContainer}</div>;\n }\n}\n\nReactElementFactory.Instance.registerElement(\n \"sv-popup\",\n (props: IPopupProps) => {\n return React.createElement(Popup, props);\n }\n);\n\nexport class PopupContainer extends SurveyElementBase<any, any> {\n constructor(props: any) {\n super(props);\n }\n handleKeydown = (event: any) => {\n this.model.onKeyDown(event);\n };\n get model(): PopupBaseViewModel {\n return this.props.model;\n }\n protected getStateElement(): Base {\n return this.model;\n }\n clickInside = (ev: any) => {\n ev.stopPropagation();\n };\n componentDidUpdate(prevProps: any, prevState: any) {\n super.componentDidUpdate(prevProps, prevState);\n if (!this.model.isPositionSet && this.model.isVisible) {\n this.model.updateOnShowing();\n }\n }\n renderContainer(popupBaseViewModel: PopupBaseViewModel): React.JSX.Element {\n const headerPopup = popupBaseViewModel.showHeader ? this.renderHeaderPopup(popupBaseViewModel) : null;\n const headerContent = !!popupBaseViewModel.title ? this.renderHeaderContent() : null;\n const content = this.renderContent();\n const footerContent = popupBaseViewModel.showFooter ? this.renderFooter(this.model) : null;\n return (\n <div\n className=\"sv-popup__container\"\n style={{\n left: popupBaseViewModel.left,\n top: popupBaseViewModel.top,\n height: popupBaseViewModel.height,\n width: popupBaseViewModel.width,\n minWidth: popupBaseViewModel.minWidth,\n }}\n onClick={(ev: any) => {\n this.clickInside(ev);\n }}\n >\n {headerPopup}\n <div className=\"sv-popup__body-content\">\n {headerContent}\n <div className=\"sv-popup__scrolling-content\">\n {content}\n </div>\n {footerContent}\n </div>\n </div>\n );\n }\n renderHeaderContent(): React.JSX.Element {\n return <div className=\"sv-popup__body-header\">{this.model.title}</div>;\n }\n renderContent(): React.JSX.Element {\n const contentComponent = ReactElementFactory.Instance.createElement(\n this.model.contentComponentName,\n this.model.contentComponentData\n );\n return <div className=\"sv-popup__content\">{contentComponent}</div>;\n }\n\n protected renderHeaderPopup(popupModel: PopupBaseViewModel): React.JSX.Element | null {\n return null;\n }\n protected renderFooter(popuModel: PopupBaseViewModel): React.JSX.Element | null {\n return (\n <div className=\"sv-popup__body-footer\">\n <SurveyActionBar model={popuModel.footerToolbar}></SurveyActionBar>\n </div>\n );\n }\n render(): React.JSX.Element {\n const container = this.renderContainer(this.model);\n const className = new CssClassBuilder()\n .append(\"sv-popup\")\n .append(this.model.styleClass)\n .toString();\n const style = { display: this.model.isVisible ? \"\" : \"none\", };\n return (\n <div\n tabIndex={-1}\n className={className}\n style={style}\n onClick={(e: any) => {\n this.model.clickOutside(e);\n }}\n onKeyDown={this.handleKeydown}\n >\n {container}\n </div>\n );\n }\n componentDidMount(): void {\n super.componentDidMount();\n if (this.model.isVisible) {\n this.model.updateOnShowing();\n }\n }\n}\nexport class PopupDropdownContainer extends PopupContainer {\n\n protected renderHeaderPopup(popupModel: PopupBaseViewModel): React.JSX.Element | null {\n const popupDropdownModel = popupModel as PopupDropdownViewModel;\n if (!popupDropdownModel) return null;\n\n return (\n <span\n style={{\n left: popupDropdownModel.pointerTarget.left,\n top: popupDropdownModel.pointerTarget.top,\n }}\n className=\"sv-popup__pointer\"\n ></span>\n );\n }\n}","import * as React from \"react\";\r\nimport { ActionDropdownViewModel, getActionDropdownButtonTarget } from \"survey-core\";\r\nimport { ReactElementFactory } from \"../../element-factory\";\r\nimport { Popup } from \"../popup/popup\";\r\nimport { SurveyActionBarItem } from \"./action-bar-item\";\r\n\r\nexport class SurveyActionBarItemDropdown extends SurveyActionBarItem {\r\n private viewModel: ActionDropdownViewModel;\r\n constructor(props: any) {\r\n super(props);\r\n }\r\n renderInnerButton() {\r\n const button = super.renderInnerButton();\r\n return (\r\n <>\r\n {button}\r\n {<Popup model={this.item.popupModel}></Popup>}\r\n </>\r\n );\r\n }\r\n componentDidMount(): void {\r\n this.viewModel = new ActionDropdownViewModel(this.item);\r\n }\r\n componentWillUnmount(): void {\r\n super.componentWillUnmount();\r\n this.viewModel.dispose();\r\n }\r\n}\r\n\r\nReactElementFactory.Instance.registerElement(\"sv-action-bar-item-dropdown\", (props) => {\r\n return React.createElement(SurveyActionBarItemDropdown, props);\r\n});\r\n","import * as React from \"react\";\nimport {\n Base,\n Action,\n ActionContainer\n} from \"survey-core\";\nimport { ReactElementFactory } from \"../../element-factory\";\nimport { SurveyElementBase } from \"../../reactquestion_element\";\nimport { SurveyAction } from \"./action-bar-item\";\n\nexport * from \"./action-bar-item-dropdown\";\nexport * from \"./action-bar-separator\";\n\ninterface IActionBarProps {\n model: ActionContainer<Action>;\n handleClick?: boolean;\n}\n\nexport class SurveyActionBar extends SurveyElementBase<IActionBarProps, any> {\n private rootRef: React.RefObject<HTMLDivElement>;\n\n constructor(props: IActionBarProps) {\n super(props);\n this.rootRef = React.createRef();\n }\n\n private get handleClick() {\n return this.props.handleClick !== undefined ? this.props.handleClick : true;\n }\n\n get model() {\n return this.props.model;\n }\n\n componentDidMount() {\n super.componentDidMount();\n if (!this.model.hasActions) return;\n const container: HTMLDivElement | null = this.rootRef.current;\n if (!!container) {\n this.model.initResponsivityManager(container, (callback) => { setTimeout(callback, 100); });\n }\n }\n componentWillUnmount() {\n super.componentWillUnmount();\n this.model.resetResponsivityManager();\n }\n componentDidUpdate(prevProps: IActionBarProps, prevState: any): void {\n super.componentDidUpdate(prevProps, prevState);\n if (prevProps.model != this.props.model) {\n prevProps.model.resetResponsivityManager();\n }\n if (!!this.model.hasActions) {\n const container: HTMLDivElement | null = this.rootRef.current;\n if (!!container) {\n this.model.initResponsivityManager(container, (callback) => { setTimeout(callback, 100); });\n }\n }\n }\n\n protected getStateElement(): Base {\n return this.model;\n }\n\n renderElement(): any {\n if (!this.model.hasActions) return null;\n const items = this.renderItems();\n return (\n <div\n ref={this.rootRef}\n className={this.model.getRootCss()}\n onClick={this.handleClick ? function (event) {\n event.stopPropagation();\n } : undefined}\n >\n {items}\n </div>\n );\n }\n renderItems() {\n return this.model.renderedActions.concat([]).map(\n (item: Action, itemIndex: number) => {\n return (\n <SurveyAction item={item} key={item.renderedId}></SurveyAction>\n );\n }\n );\n }\n}\n\nReactElementFactory.Instance.registerElement(\"sv-action-bar\", (props) => {\n return React.createElement(\n SurveyActionBar,\n (props as any) as IActionBarProps\n );\n});\n","import * as React from \"react\";\nimport { SurveyElementCore, ITitleOwner } from \"survey-core\";\nimport { SurveyElementBase } from \"../../reactquestion_element\";\n\nexport class TitleContent extends React.Component<any, any> {\n constructor(props: any) {\n super(props);\n }\n\n private get cssClasses() {\n return this.props.cssClasses;\n }\n\n private get element(): SurveyElementCore {\n return this.props.element;\n }\n render(): React.JSX.Element {\n if (this.element.isTitleRenderedAsString)\n return SurveyElementBase.renderLocString(this.element.locTitle);\n var spans = this.renderTitleSpans(this.element.getTitleOwner(), this.cssClasses);\n return <>{spans}</>;\n }\n protected renderTitleSpans(element: ITitleOwner, cssClasses: any): Array<React.JSX.Element> {\n var getSpaceSpan = (key: any) => {\n return (\n <span data-key={key} key={key}>\n &nbsp;\n </span>\n );\n };\n var spans: Array<React.JSX.Element> = [];\n if (element.isRequireTextOnStart) {\n spans.push(this.renderRequireText(element));\n spans.push(getSpaceSpan(\"req-sp\"));\n }\n var questionNumber = element.no;\n if (questionNumber) {\n spans.push(\n <span\n data-key={\"q_num\"}\n key={\"q_num\"}\n className={element.cssTitleNumber}\n style={{ position: \"static\" }}\n aria-hidden={true}\n >\n {questionNumber}\n </span>\n );\n spans.push(getSpaceSpan(\"num-sp\"));\n }\n if (element.isRequireTextBeforeTitle) {\n spans.push(this.renderRequireText(element));\n spans.push(getSpaceSpan(\"req-sp\"));\n }\n spans.push(\n SurveyElementBase.renderLocString(element.locTitle, null, \"q_title\")\n );\n if (element.isRequireTextAfterTitle) {\n spans.push(getSpaceSpan(\"req-sp\"));\n spans.push(this.renderRequireText(element));\n }\n return spans;\n }\n\n private renderRequireText(element: ITitleOwner): React.JSX.Element {\n return (\n <span\n data-key={\"req-text\"}\n key={\"req-text\"}\n className={element.cssRequiredMark}\n aria-hidden={true}\n >\n {element.requiredMark}\n </span>\n );\n }\n}\n","import * as React from \"react\";\nimport { SurveyElement, RendererFactory } from \"survey-core\";\nimport { ReactElementFactory } from \"../../element-factory\";\nimport { SurveyActionBar } from \"../action-bar/action-bar\";\nimport { TitleContent } from \"./title-content\";\n\nexport class TitleActions extends React.Component<any, any> {\n protected get cssClasses() {\n return this.props.cssClasses;\n }\n protected get element(): SurveyElement {\n return this.props.element;\n }\n\n render(): React.JSX.Element {\n const titleContent: React.JSX.Element = <TitleContent element={this.element} cssClasses={this.cssClasses}></TitleContent>;\n if (!this.element.hasTitleActions) return titleContent;\n return (\n <div className=\"sv-title-actions\">\n <span className=\"sv-title-actions__title\">{titleContent}</span>\n <SurveyActionBar model={this.element.getTitleToolbar()}></SurveyActionBar>\n </div>\n );\n }\n}\n\nRendererFactory.Instance.registerRenderer(\n \"element\",\n \"title-actions\",\n \"sv-title-actions\"\n);\n\nReactElementFactory.Instance.registerElement(\"sv-title-actions\", (props) => {\n return React.createElement(TitleActions, props);\n});\n","import * as React from \"react\";\nimport { SurveyElement, SurveyElementCore, doKey2ClickUp } from \"survey-core\";\nimport { TitleActions } from \"./title-actions\";\nimport { SvgIcon } from \"../svg-icon/svg-icon\";\n\nexport class TitleElement extends React.Component<any, any> {\n constructor(props: any) {\n super(props);\n }\n private get element(): SurveyElement {\n return this.props.element;\n }\n renderTitleExpandableSvg() {\n if (!this.element.getCssTitleExpandableSvg()) return null;\n let iconName = this.element.isExpanded ? \"icon-collapse-16x16\" : \"icon-expand-16x16\";\n\n return <SvgIcon\n className={this.element.getCssTitleExpandableSvg()}\n iconName={iconName}\n size={\"auto\"}\n ></SvgIcon>;\n }\n render(): React.JSX.Element | any {\n const element = this.element;\n if (!element || !element.hasTitle) return null;\n const ariaLabel = element.titleAriaLabel || undefined;\n\n const titleExpandableSvg = this.renderTitleExpandableSvg();\n\n const titleContent = (\n <TitleActions\n element={element}\n cssClasses={element.cssClasses}\n ></TitleActions>\n );\n\n let onClick: undefined | ((e: any) => void) = undefined;\n let onKeyUp: undefined | ((e: any) => void) = undefined;\n if (element.hasTitleEvents) {\n onKeyUp = (evt: any) => {\n doKey2ClickUp(evt.nativeEvent);\n };\n }\n\n const CustomTag = element.titleTagName as keyof JSX.IntrinsicElements;\n return (\n <CustomTag\n className={element.cssTitle}\n id={element.ariaTitleId}\n aria-label={ariaLabel}\n tabIndex={element.titleTabIndex}\n aria-expanded={element.titleAriaExpanded}\n role={element.titleAriaRole}\n onClick={onClick}\n onKeyUp={onKeyUp}\n >\n {titleExpandableSvg}\n {titleContent}\n </CustomTag>\n );\n }\n}\n","import { HashTable } from \"survey-core\";\n\nexport