@o2s/modules.surveyjs 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { Typography } from '@o2s/ui/elements/typography';
3
+ export const Fieldset = ({ legend, children, optionalLabel }) => {
4
+ return (React.createElement("fieldset", { className: 'border-0 m-0 p-0' },
5
+ React.createElement("legend", { className: 'items-center gap-2 hidden' },
6
+ React.createElement(Typography, { variant: "small" }, legend),
7
+ React.createElement(Typography, { variant: "small" }, optionalLabel)),
8
+ React.createElement("div", { className: 'flex flex-col gap-4' }, children)));
9
+ };
@@ -3,9 +3,7 @@ import { ReactElementFactory, SurveyNavigationButton } from 'survey-react-ui';
3
3
  import { Button } from '@o2s/ui/elements/button';
4
4
  class CustomSurveyNavigationButton extends SurveyNavigationButton {
5
5
  renderElement() {
6
- return (<Button disabled={this.item.disabled} onMouseDown={this.item.data && this.item.data.mouseDown} onClick={this.item.action}>
7
- {this.item.title}
8
- </Button>);
6
+ return (React.createElement(Button, { disabled: this.item.disabled, onMouseDown: this.item.data && this.item.data.mouseDown, onClick: this.item.action }, this.item.title));
9
7
  }
10
8
  }
11
9
  ReactElementFactory.Instance.registerElement('sv-nav-btn', (props) => {
@@ -6,7 +6,7 @@ class CustomSurveyPanel extends SurveyPanel {
6
6
  hasBeenExpanded1 = false;
7
7
  renderElement() {
8
8
  const header = this.renderHeader();
9
- const errors = (<SurveyElementErrors element={this.panelBase} cssClasses={this.panelBase.cssClasses} creator={this.creator}/>);
9
+ const errors = (React.createElement(SurveyElementErrors, { element: this.panelBase, cssClasses: this.panelBase.cssClasses, creator: this.creator }));
10
10
  const style = {
11
11
  paddingLeft: this.panel.innerPaddingLeft,
12
12
  display: !this.panel.isCollapsed ? undefined : 'none',
@@ -24,31 +24,25 @@ class CustomSurveyPanel extends SurveyPanel {
24
24
  if (this.panelBase)
25
25
  this.panelBase.focusIn();
26
26
  };
27
- const inner = (<>
28
- {header}
29
- {content}
30
- {errors}
31
- </>);
32
- return (<>
33
- <div ref={this.rootRef} className="rounded-lg border bg-card text-card-foreground !shadow-xs !p-4 !m-0" onFocus={focusIn} id={this.panelBase.id}>
34
- {inner}
35
- </div>
36
- </>);
27
+ const inner = (React.createElement(React.Fragment, null,
28
+ header,
29
+ content,
30
+ errors));
31
+ return (React.createElement(React.Fragment, null,
32
+ React.createElement("div", { ref: this.rootRef, className: "rounded-lg border bg-card text-card-foreground !shadow-xs !p-4 !m-0", onFocus: focusIn, id: this.panelBase.id }, inner)));
37
33
  }
38
34
  renderHeader() {
39
35
  if (!this.panel.hasTitle && !this.panel.hasDescription) {
40
- return <></>;
36
+ return React.createElement(React.Fragment, null);
41
37
  }
42
- return (<div className={'my-4 first:mt-0'}>
43
- <Typography>{this.panel.title}</Typography>
44
- </div>);
38
+ return (React.createElement("div", { className: 'my-4 first:mt-0' },
39
+ React.createElement(Typography, null, this.panel.title)));
45
40
  }
46
41
  renderContent(style, rows, className) {
47
42
  const bottom = this.renderBottom();
48
- return (<div style={style} className={cn(className, 'p-0')} id={this.panel.contentId}>
49
- {bottom}
50
- {rows}
51
- </div>);
43
+ return (React.createElement("div", { style: style, className: cn(className, 'p-0'), id: this.panel.contentId },
44
+ bottom,
45
+ rows));
52
46
  }
53
47
  }
54
48
  ReactElementFactory.Instance.registerElement('panel', function (props) {
@@ -12,35 +12,28 @@ class CustomSurveyQuestion extends SurveyQuestion {
12
12
  const errorsAboveQuestion = this.question.showErrorsAboveQuestion ? this.renderErrors() : null;
13
13
  const errorsBelowQuestion = this.question.showErrorsBelowQuestion ? this.renderErrors() : null;
14
14
  const questionContent = this.wrapQuestionContent(this.renderQuestionContent());
15
- return (<>
16
- <div id={question.id} className={'h-full w-full box-border !p-0'} role={question.ariaRole} aria-required={this.question.ariaRequired} aria-invalid={this.question.ariaInvalid} aria-labelledby={question.ariaLabelledBy} aria-describedby={question.ariaDescribedBy} aria-expanded={question.ariaExpanded === null ? undefined : question.ariaExpanded === 'true'}>
17
- {headerTop}
18
- {errorsAboveQuestion}
19
- {questionContent}
20
- {errorsBelowQuestion}
21
- {headerBottom}
22
- </div>
23
- </>);
15
+ return (React.createElement(React.Fragment, null,
16
+ React.createElement("div", { id: question.id, className: 'h-full w-full box-border !p-0', role: question.ariaRole, "aria-required": this.question.ariaRequired, "aria-invalid": this.question.ariaInvalid, "aria-labelledby": question.ariaLabelledBy, "aria-describedby": question.ariaDescribedBy, "aria-expanded": question.ariaExpanded === null ? undefined : question.ariaExpanded === 'true' },
17
+ headerTop,
18
+ errorsAboveQuestion,
19
+ questionContent,
20
+ errorsBelowQuestion,
21
+ headerBottom)));
24
22
  }
25
23
  renderHeader() {
26
24
  if (this.question.getType() === 'text' ||
27
25
  this.question.getType() === 'comment' ||
28
26
  this.question.getType() === 'dropdown') {
29
- return <></>;
27
+ return React.createElement(React.Fragment, null);
30
28
  }
31
- return (<div className={'header my-2 first:mt-0'}>
32
- <Label htmlFor={this.question.id}>{this.question.title}</Label>
33
- </div>);
29
+ return (React.createElement("div", { className: 'header my-2 first:mt-0' },
30
+ React.createElement(Label, { htmlFor: this.question.id }, this.question.title)));
34
31
  }
35
32
  renderErrors() {
36
33
  if (!this.question.errors?.length) {
37
- return <></>;
34
+ return React.createElement(React.Fragment, null);
38
35
  }
39
- return (<div role="alert" aria-live="polite" className={'mt-2'}>
40
- {this.question.errors.map((error) => (<Typography variant="small" className="text-destructive" key={error.locText.renderedHtml}>
41
- {this.renderLocString(error.locText)}
42
- </Typography>))}
43
- </div>);
36
+ return (React.createElement("div", { role: "alert", "aria-live": "polite", className: 'mt-2' }, this.question.errors.map((error) => (React.createElement(Typography, { variant: "small", className: "text-destructive", key: error.locText.renderedHtml }, this.renderLocString(error.locText))))));
44
37
  }
45
38
  }
46
39
  ReactElementFactory.Instance.registerElement('question', function (props) {
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ import { RendererFactory } from 'survey-core';
3
+ import { ReactQuestionFactory, SurveyQuestionBoolean } from 'survey-react-ui';
4
+ import { cn } from '@o2s/ui/lib/utils';
5
+ import { ToggleGroup, ToggleGroupItem } from '@o2s/ui/elements/toggle-group';
6
+ class CustomSurveyQuestionBoolean extends SurveyQuestionBoolean {
7
+ renderElement() {
8
+ return (React.createElement(ToggleGroup, { type: "single", value: this.question.booleanValue === null ? undefined : this.question.booleanValue ? 'true' : 'false', size: "default", variant: "outline", disabled: this.question.readOnly, onValueChange: (value) => {
9
+ this.question.booleanValue = value === 'true';
10
+ }, className: cn(this.question.errors?.length && 'border-destructive', 'justify-start'), "aria-label": this.question.title, "aria-invalid": !!this.question.errors?.length },
11
+ React.createElement(ToggleGroupItem, { value: this.question.swapOrder ? 'true' : 'false', className: cn(this.question.errors?.length && 'border-destructive', 'justify-center min-w-12') }, this.renderLocString(this.question.locLabelLeft)),
12
+ React.createElement(ToggleGroupItem, { value: this.question.swapOrder ? 'false' : 'true', className: cn(this.question.errors?.length && 'border-destructive', 'justify-center min-w-12') }, this.renderLocString(this.question.locLabelRight))));
13
+ }
14
+ }
15
+ ReactQuestionFactory.Instance.registerQuestion('CustomSurveyQuestionBoolean', function (props) {
16
+ return React.createElement(CustomSurveyQuestionBoolean, props);
17
+ });
18
+ RendererFactory.Instance.registerRenderer('boolean', 'boolean-o2s', 'CustomSurveyQuestionBoolean');
@@ -6,9 +6,7 @@ import { CheckboxWithLabel } from '@o2s/ui/elements/checkbox';
6
6
  import { Fieldset } from '../Components/Fieldset/Fieldset';
7
7
  class CustomSurveyQuestionCheckbox extends SurveyQuestionCheckbox {
8
8
  renderElement() {
9
- return (<Fieldset legend={this.question.locTitle.renderedHtml}>
10
- {this.getItems('', this.question.dataChoices)}
11
- </Fieldset>);
9
+ return (React.createElement(Fieldset, { legend: this.question.locTitle.renderedHtml }, this.getItems('', this.question.dataChoices)));
12
10
  }
13
11
  }
14
12
  ReactQuestionFactory.Instance.registerQuestion('CustomSurveyQuestionCheckbox ', function (props) {
@@ -17,9 +15,9 @@ ReactQuestionFactory.Instance.registerQuestion('CustomSurveyQuestionCheckbox ',
17
15
  RendererFactory.Instance.registerRenderer('checkbox', 'checkbox-o2s', 'CustomSurveyQuestionCheckbox ');
18
16
  class CustomSurveyQuestionCheckboxItem extends SurveyQuestionCheckboxItem {
19
17
  renderElement() {
20
- return (<CheckboxWithLabel id={this.question.getItemId(this.item)} value={this.item.value} checked={this.question.isItemSelected(this.item)} disabled={this.question.readOnly} onCheckedChange={(value) => {
18
+ return (React.createElement(CheckboxWithLabel, { id: this.question.getItemId(this.item), value: this.item.value, checked: this.question.isItemSelected(this.item), disabled: this.question.readOnly, onCheckedChange: (value) => {
21
19
  this.question.clickItemHandler(this.item, value === true);
22
- }} aria-invalid={!!this.question.errors?.length} className={cn(this.question.errors?.length && 'border-destructive')} label={this.renderLocString(this.item.locText, this.textStyle)}/>);
20
+ }, "aria-invalid": !!this.question.errors?.length, className: cn(this.question.errors?.length && 'border-destructive'), label: this.renderLocString(this.item.locText, this.textStyle) }));
23
21
  }
24
22
  }
25
23
  ReactElementFactory.Instance.registerElement('CustomSurveyQuestionCheckboxItem', function (props) {
@@ -5,9 +5,9 @@ import { cn } from '@o2s/ui/lib/utils';
5
5
  import { TextareaWithLabel } from '@o2s/ui/elements/textarea';
6
6
  class CustomSurveyQuestionComment extends SurveyQuestionComment {
7
7
  renderElement() {
8
- return (<TextareaWithLabel id={this.question.name} name={this.question.name} value={this.question.value} placeholder={this.question.placeholder} disabled={this.question.readOnly} onChange={(event) => {
8
+ return (React.createElement(TextareaWithLabel, { id: this.question.name, name: this.question.name, value: this.question.value, placeholder: this.question.placeholder, disabled: this.question.readOnly, onChange: (event) => {
9
9
  this.question.value = event.target.value;
10
- }} aria-invalid={!!this.question.errors?.length} className={cn(this.question.errors?.length && 'border-destructive')} label={this.question.title}/>);
10
+ }, "aria-invalid": !!this.question.errors?.length, className: cn(this.question.errors?.length && 'border-destructive'), label: this.question.title }));
11
11
  }
12
12
  }
13
13
  ReactQuestionFactory.Instance.registerQuestion('CustomSurveyQuestionComment', function (props) {
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import { RendererFactory } from 'survey-core';
3
+ import { ReactQuestionFactory, SurveyQuestionDropdown } from 'survey-react-ui';
4
+ import { cn } from '@o2s/ui/lib/utils';
5
+ import { SelectContent, SelectItem, SelectTrigger, SelectValue, SelectWithTitle } from '@o2s/ui/elements/select';
6
+ class CustomSurveyQuestionDropdown extends SurveyQuestionDropdown {
7
+ renderElement() {
8
+ return (React.createElement("div", { className: "grid w-full items-center gap-2" },
9
+ React.createElement(SelectWithTitle, { value: this.question.value, onValueChange: (value) => {
10
+ this.question.value = value;
11
+ }, disabled: this.question.readOnly, label: this.question.title, id: this.question.name },
12
+ React.createElement(SelectTrigger, { className: cn(this.question.errors?.length && 'border-destructive'), id: this.question.id },
13
+ React.createElement(SelectValue, { placeholder: this.question.renderedPlaceholder })),
14
+ React.createElement(SelectContent, null, this.question.visibleChoices.map((choice) => (React.createElement(SelectItem, { key: choice.value, value: choice.value }, choice.text)))))));
15
+ }
16
+ }
17
+ ReactQuestionFactory.Instance.registerQuestion('CustomSurveyQuestionDropdown', function (props) {
18
+ return React.createElement(CustomSurveyQuestionDropdown, props);
19
+ });
20
+ RendererFactory.Instance.registerRenderer('dropdown', 'dropdown-o2s', 'CustomSurveyQuestionDropdown');
@@ -5,13 +5,11 @@ import { cn } from '@o2s/ui/lib/utils';
5
5
  import { RadioGroup, RadioGroupItemWithLabel } from '@o2s/ui/elements/radio-group';
6
6
  class CustomSurveyQuestionRadiogroup extends SurveyQuestionRadiogroup {
7
7
  renderElement() {
8
- return (<RadioGroup id={this.question.questionName} disabled={this.question.readOnly} name={this.question.questionName} onValueChange={(value) => {
8
+ return (React.createElement(RadioGroup, { id: this.question.questionName, disabled: this.question.readOnly, name: this.question.questionName, onValueChange: (value) => {
9
9
  this.question.renderedValue = value;
10
- }} defaultValue={this.question.value} orientation="vertical" aria-invalid={!!this.question.errors?.length} aria-label={this.question.title} className="flex flex-col gap-4">
11
- <>{this.getItems('', this.question.dataChoices)}</>
12
- {/*empty element to overcome RadioGroup requiring multiple children*/}
13
- <></>
14
- </RadioGroup>);
10
+ }, defaultValue: this.question.value, orientation: "vertical", "aria-invalid": !!this.question.errors?.length, "aria-label": this.question.title, className: "flex flex-col gap-4" },
11
+ React.createElement(React.Fragment, null, this.getItems('', this.question.dataChoices)),
12
+ React.createElement(React.Fragment, null)));
15
13
  }
16
14
  }
17
15
  ReactQuestionFactory.Instance.registerQuestion('CustomSurveyQuestionRadiogroup', function (props) {
@@ -20,7 +18,7 @@ ReactQuestionFactory.Instance.registerQuestion('CustomSurveyQuestionRadiogroup',
20
18
  RendererFactory.Instance.registerRenderer('radiogroup', 'radiogroup-o2s', 'CustomSurveyQuestionRadiogroup');
21
19
  class CustomSurveyQuestionRadioItem extends SurveyQuestionRadioItem {
22
20
  renderElement() {
23
- return (<RadioGroupItemWithLabel value={this.item.value} id={this.item.value} className={cn(this.question.errors?.length && 'border-destructive', 'justify-start')} label={this.renderLocString(this.item.locText, this.textStyle)} labelClassName="text-sm leading-none cursor-pointer peer-disabled:opacity-70"/>);
21
+ return (React.createElement(RadioGroupItemWithLabel, { value: this.item.value, id: this.item.value, className: cn(this.question.errors?.length && 'border-destructive', 'justify-start'), label: this.renderLocString(this.item.locText, this.textStyle), labelClassName: "text-sm leading-none cursor-pointer peer-disabled:opacity-70" }));
24
22
  }
25
23
  }
26
24
  ReactElementFactory.Instance.registerElement('CustomSurveyQuestionRadioItem', function (props) {
@@ -0,0 +1,56 @@
1
+ 'use client';
2
+ import { format } from 'date-fns';
3
+ import { de, enUS, pl } from 'date-fns/locale';
4
+ import { CalendarIcon } from 'lucide-react';
5
+ import { useLocale } from 'next-intl';
6
+ import React, { useState } from 'react';
7
+ import { RendererFactory } from 'survey-core';
8
+ import { ReactQuestionFactory } from 'survey-react-ui';
9
+ import { cn } from '@o2s/ui/lib/utils';
10
+ import { Button } from '@o2s/ui/elements/button';
11
+ import { Calendar } from '@o2s/ui/elements/calendar';
12
+ import { InputWithLabel } from '@o2s/ui/elements/input';
13
+ import { Label } from '@o2s/ui/elements/label';
14
+ import { Popover, PopoverContent, PopoverTrigger } from '@o2s/ui/elements/popover';
15
+ const localeMap = {
16
+ en: {
17
+ locale: enUS,
18
+ format: 'MM.dd.yyyy',
19
+ },
20
+ pl: {
21
+ locale: pl,
22
+ format: 'dd.MM.yyyy',
23
+ },
24
+ de: {
25
+ locale: de,
26
+ format: 'dd.MM.yyyy',
27
+ },
28
+ };
29
+ const CustomSurveyQuestionText = (props) => {
30
+ const [open, setOpen] = useState(false);
31
+ const locale = useLocale();
32
+ const question = props.question;
33
+ if (question.inputType === 'date') {
34
+ return (React.createElement("div", { className: "grid w-full items-center gap-2" },
35
+ React.createElement(Label, { htmlFor: question.inputId }, question.title),
36
+ React.createElement(Popover, { open: open, onOpenChange: setOpen },
37
+ React.createElement(PopoverTrigger, { asChild: true, disabled: question.readOnly },
38
+ React.createElement(Button, { variant: 'outline', className: cn('w-full justify-start text-left font-normal', !question.value && 'text-muted-foreground', question.errors?.length && 'border-destructive'), name: question.inputId, disabled: question.readOnly },
39
+ React.createElement(CalendarIcon, null),
40
+ question.value ? (format(new Date(question.value), localeMap[locale].format || localeMap.en.format, {
41
+ locale: localeMap[locale].locale || localeMap.en.locale,
42
+ })) : (React.createElement("span", null, question.placeholder)))),
43
+ React.createElement(PopoverContent, { className: "w-auto p-0" },
44
+ React.createElement(Calendar, { mode: "single", selected: question.value ? new Date(question.value) : undefined, initialFocus: true, id: question.inputId, onSelect: (value) => {
45
+ question.value = value?.toISOString() || null;
46
+ setOpen(false);
47
+ }, showYearSwitcher: true, locale: localeMap[locale].locale || localeMap.en.locale })))));
48
+ }
49
+ return (React.createElement(InputWithLabel, { id: question.inputId, name: question.inputId, value: question.value?.toString() || '', placeholder: question.placeholder, disabled: question.isDisplayMode, onChange: (event) => {
50
+ question.value = event.target.value;
51
+ }, "aria-invalid": !!question.errors?.length, className: cn(question.errors?.length && 'border-destructive', 'font-regular'), label: question.title }));
52
+ };
53
+ ReactQuestionFactory.Instance.registerQuestion('CustomSurveyQuestionText', function (props) {
54
+ return React.createElement(CustomSurveyQuestionText, props);
55
+ });
56
+ RendererFactory.Instance.registerRenderer('text', 'text-o2s', 'CustomSurveyQuestionText');
@@ -117,7 +117,6 @@ export const Survey = ({ code, labels, locale, accessToken }) => {
117
117
  };
118
118
  loadSurvey();
119
119
  }, [dispatch, code, locale, accessToken, labels]);
120
- return (<LoadingOverlay isActive={state.isLoading} fallback={<Loading bars={12}/>}>
121
- <div className={'min-h-[400px]'}>{state.model && <SurveySDK model={state.model}/>}</div>
122
- </LoadingOverlay>);
120
+ return (React.createElement(LoadingOverlay, { isActive: state.isLoading, fallback: React.createElement(Loading, { bars: 12 }) },
121
+ React.createElement("div", { className: 'min-h-[400px]' }, state.model && React.createElement(SurveySDK, { model: state.model }))));
123
122
  };