mirror of
https://github.com/formbricks/formbricks.git
synced 2025-12-30 18:30:32 -06:00
apply prettier in react lib, make packages private
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"name": "@formbricks/database",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.mjs",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"name": "eslint-config-formbricks",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@@ -12,8 +13,5 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^4.8.4"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
{
|
||||
"name": "@snoopforms/prettier-config",
|
||||
"name": "@formbricks/prettier-config",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"license": "MIT",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "^2.7.1",
|
||||
"prettier-plugin-tailwindcss": "^0.1.13"
|
||||
|
||||
@@ -27,20 +27,8 @@ Use the SnoopForm components to build your form easily.
|
||||
```jsx
|
||||
<SnoopForm formId="abcd">
|
||||
<SnoopPage name="basicInfo">
|
||||
<SnoopElement
|
||||
type="text"
|
||||
name="name"
|
||||
label="Your name"
|
||||
help="Please use your real name"
|
||||
required
|
||||
/>
|
||||
<SnoopElement
|
||||
type="textarea"
|
||||
name="about"
|
||||
label="About you"
|
||||
help="e.g. your hobbies etc."
|
||||
required
|
||||
/>
|
||||
<SnoopElement type="text" name="name" label="Your name" help="Please use your real name" required />
|
||||
<SnoopElement type="textarea" name="about" label="About you" help="e.g. your hobbies etc." required />
|
||||
<SnoopElement name="submit" type="submit" label="Submit" />
|
||||
</SnoopPage>
|
||||
<SnoopPage name="advancedInfo">
|
||||
@@ -48,7 +36,7 @@ Use the SnoopForm components to build your form easily.
|
||||
type="checkbox"
|
||||
name="programming-lanuguages"
|
||||
label="What programming languages do you love?"
|
||||
options={['C++', 'Javascript', 'Scala', 'Assembler']}
|
||||
options={["C++", "Javascript", "Scala", "Assembler"]}
|
||||
/>
|
||||
<SnoopElement name="submit" type="submit" label="Submit" />
|
||||
</SnoopPage>
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
import { RadioGroup } from '@headlessui/react';
|
||||
import React, { FC, useContext, useEffect, useState } from 'react';
|
||||
import { getOptionValue, setSubmissionValue } from '../../lib/elements';
|
||||
import { classNamesConcat } from '../../lib/utils';
|
||||
import { ClassNames, Option } from '../../types';
|
||||
import {
|
||||
SubmissionContext,
|
||||
SubmitHandlerContext,
|
||||
} from '../SnoopForm/SnoopForm';
|
||||
import { PageContext } from '../SnoopPage/SnoopPage';
|
||||
import { RadioGroup } from "@headlessui/react";
|
||||
import React, { FC, useContext, useEffect, useState } from "react";
|
||||
import { getOptionValue, setSubmissionValue } from "../../lib/elements";
|
||||
import { classNamesConcat } from "../../lib/utils";
|
||||
import { ClassNames, Option } from "../../types";
|
||||
import { SubmissionContext, SubmitHandlerContext } from "../SnoopForm/SnoopForm";
|
||||
import { PageContext } from "../SnoopPage/SnoopPage";
|
||||
|
||||
interface Props {
|
||||
name: string;
|
||||
@@ -21,15 +18,7 @@ interface Props {
|
||||
required?: boolean;
|
||||
}
|
||||
|
||||
export const Cards: FC<Props> = ({
|
||||
name,
|
||||
label,
|
||||
help,
|
||||
cols,
|
||||
autoSubmit,
|
||||
options,
|
||||
classNames,
|
||||
}) => {
|
||||
export const Cards: FC<Props> = ({ name, label, help, cols, autoSubmit, options, classNames }) => {
|
||||
const { submission, setSubmission }: any = useContext(SubmissionContext);
|
||||
const handleSubmit = useContext(SubmitHandlerContext);
|
||||
const pageName = useContext(PageContext);
|
||||
@@ -45,13 +34,7 @@ export const Cards: FC<Props> = ({
|
||||
return (
|
||||
<div>
|
||||
{label && (
|
||||
<label
|
||||
className={
|
||||
classNames.label || 'block text-sm font-medium text-gray-700'
|
||||
}
|
||||
>
|
||||
{label}
|
||||
</label>
|
||||
<label className={classNames.label || "block text-sm font-medium text-gray-700"}>{label}</label>
|
||||
)}
|
||||
<RadioGroup
|
||||
value={submission[pageName] ? submission[pageName][name] : undefined}
|
||||
@@ -62,37 +45,33 @@ export const Cards: FC<Props> = ({
|
||||
setTriggerSubmit(true);
|
||||
}
|
||||
}}
|
||||
className="mt-2"
|
||||
>
|
||||
<RadioGroup.Label className="sr-only">
|
||||
Choose an option
|
||||
</RadioGroup.Label>
|
||||
className="mt-2">
|
||||
<RadioGroup.Label className="sr-only">Choose an option</RadioGroup.Label>
|
||||
<div
|
||||
className={classNamesConcat(
|
||||
'grid gap-3',
|
||||
"grid gap-3",
|
||||
(cols && cols === 1) || options.length === 1
|
||||
? 'grid-cols-1'
|
||||
? "grid-cols-1"
|
||||
: (cols && cols === 2) || options.length === 2
|
||||
? 'grid-cols-2'
|
||||
? "grid-cols-2"
|
||||
: (cols && cols === 3) || options.length === 3
|
||||
? 'grid-cols-3'
|
||||
? "grid-cols-3"
|
||||
: (cols && cols === 4) || options.length === 4
|
||||
? 'grid-cols-4'
|
||||
? "grid-cols-4"
|
||||
: (cols && cols === 5) || options.length === 5
|
||||
? 'grid-cols-5'
|
||||
? "grid-cols-5"
|
||||
: (cols && cols === 6) || options.length === 6
|
||||
? 'grid-cols-6'
|
||||
? "grid-cols-6"
|
||||
: (cols && cols === 7) || options.length === 7
|
||||
? 'grid-cols-7'
|
||||
? "grid-cols-7"
|
||||
: (cols && cols === 8) || options.length === 8
|
||||
? 'grid-cols-8'
|
||||
? "grid-cols-8"
|
||||
: (cols && cols === 9) || options.length === 9
|
||||
? 'grid-cols-9'
|
||||
? "grid-cols-9"
|
||||
: cols === 10
|
||||
? 'grid-cols-10'
|
||||
: 'grid-cols-1 sm:grid-cols-6'
|
||||
)}
|
||||
>
|
||||
? "grid-cols-10"
|
||||
: "grid-cols-1 sm:grid-cols-6"
|
||||
)}>
|
||||
{options.map((option) => (
|
||||
<RadioGroup.Option
|
||||
key={getOptionValue(option)}
|
||||
@@ -100,27 +79,20 @@ export const Cards: FC<Props> = ({
|
||||
value={option}
|
||||
className={({ active, checked }) =>
|
||||
classNamesConcat(
|
||||
'cursor-pointer focus:outline-none',
|
||||
active ? 'ring-2 ring-offset-2 ring-gray-500' : '',
|
||||
"cursor-pointer focus:outline-none",
|
||||
active ? "ring-2 ring-gray-500 ring-offset-2" : "",
|
||||
checked
|
||||
? 'bg-gray-600 border-transparent text-white hover:bg-gray-700'
|
||||
: 'bg-white border-gray-200 text-gray-900 hover:bg-gray-50',
|
||||
'border rounded-md py-3 px-3 flex items-center justify-center text-sm font-medium uppercase sm:flex-1'
|
||||
? "border-transparent bg-gray-600 text-white hover:bg-gray-700"
|
||||
: "border-gray-200 bg-white text-gray-900 hover:bg-gray-50",
|
||||
"flex items-center justify-center rounded-md border py-3 px-3 text-sm font-medium uppercase sm:flex-1"
|
||||
)
|
||||
}
|
||||
>
|
||||
<RadioGroup.Label as="span">
|
||||
{getOptionValue(option)}
|
||||
</RadioGroup.Label>
|
||||
}>
|
||||
<RadioGroup.Label as="span">{getOptionValue(option)}</RadioGroup.Label>
|
||||
</RadioGroup.Option>
|
||||
))}
|
||||
</div>
|
||||
</RadioGroup>
|
||||
{help && (
|
||||
<p className={classNames.help || 'mt-2 text-sm text-gray-500'}>
|
||||
{help}
|
||||
</p>
|
||||
)}
|
||||
{help && <p className={classNames.help || "mt-2 text-sm text-gray-500"}>{help}</p>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React, { FC, useContext, useEffect, useState } from 'react';
|
||||
import { setSubmissionValue } from '../../lib/elements';
|
||||
import { ClassNames } from '../../types';
|
||||
import { SubmissionContext } from '../SnoopForm/SnoopForm';
|
||||
import { PageContext } from '../SnoopPage/SnoopPage';
|
||||
import React, { FC, useContext, useEffect, useState } from "react";
|
||||
import { setSubmissionValue } from "../../lib/elements";
|
||||
import { ClassNames } from "../../types";
|
||||
import { SubmissionContext } from "../SnoopForm/SnoopForm";
|
||||
import { PageContext } from "../SnoopPage/SnoopPage";
|
||||
|
||||
interface Option {
|
||||
label: string;
|
||||
@@ -19,13 +19,7 @@ interface Props {
|
||||
required?: boolean;
|
||||
}
|
||||
|
||||
export const Checkbox: FC<Props> = ({
|
||||
name,
|
||||
label,
|
||||
help,
|
||||
options,
|
||||
classNames,
|
||||
}) => {
|
||||
export const Checkbox: FC<Props> = ({ name, label, help, options, classNames }) => {
|
||||
const [checked, setChecked] = useState<string[]>([]);
|
||||
const { setSubmission }: any = useContext(SubmissionContext);
|
||||
const pageName = useContext(PageContext);
|
||||
@@ -37,38 +31,26 @@ export const Checkbox: FC<Props> = ({
|
||||
return (
|
||||
<div>
|
||||
{label && (
|
||||
<label
|
||||
className={
|
||||
classNames.label || 'block text-sm font-medium text-gray-700'
|
||||
}
|
||||
>
|
||||
{label}
|
||||
</label>
|
||||
<label className={classNames.label || "block text-sm font-medium text-gray-700"}>{label}</label>
|
||||
)}
|
||||
<div className="mt-2 space-y-2">
|
||||
{options.map((option) => (
|
||||
<div
|
||||
className="relative flex items-start"
|
||||
key={typeof option === 'object' ? option.value : option}
|
||||
>
|
||||
<div className="flex items-center h-5">
|
||||
<div className="relative flex items-start" key={typeof option === "object" ? option.value : option}>
|
||||
<div className="flex h-5 items-center">
|
||||
<input
|
||||
id={typeof option === 'object' ? option.value : option}
|
||||
name={typeof option === 'object' ? option.value : option}
|
||||
id={typeof option === "object" ? option.value : option}
|
||||
name={typeof option === "object" ? option.value : option}
|
||||
type="checkbox"
|
||||
className={
|
||||
classNames.element ||
|
||||
'focus:ring-slate-500 h-4 w-4 text-slate-600 border-gray-300 rounded-sm'
|
||||
"h-4 w-4 rounded-sm border-gray-300 text-slate-600 focus:ring-slate-500"
|
||||
}
|
||||
checked={
|
||||
typeof option === 'object'
|
||||
? checked.includes(option.value)
|
||||
: checked.includes(option)
|
||||
typeof option === "object" ? checked.includes(option.value) : checked.includes(option)
|
||||
}
|
||||
onChange={(e) => {
|
||||
const newChecked: string[] = [...checked];
|
||||
const value =
|
||||
typeof option === 'object' ? option.value : option;
|
||||
const value = typeof option === "object" ? option.value : option;
|
||||
if (e.target.checked) {
|
||||
newChecked.push(value);
|
||||
} else {
|
||||
@@ -84,22 +66,15 @@ export const Checkbox: FC<Props> = ({
|
||||
</div>
|
||||
<div className="ml-3 text-base">
|
||||
<label
|
||||
htmlFor={typeof option === 'object' ? option.value : option}
|
||||
className={
|
||||
classNames.elementLabel || 'font-medium text-gray-700'
|
||||
}
|
||||
>
|
||||
{typeof option === 'object' ? option.label : option}
|
||||
htmlFor={typeof option === "object" ? option.value : option}
|
||||
className={classNames.elementLabel || "font-medium text-gray-700"}>
|
||||
{typeof option === "object" ? option.label : option}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{help && (
|
||||
<p className={classNames.help || 'mt-2 text-sm text-gray-500'}>
|
||||
{help}
|
||||
</p>
|
||||
)}
|
||||
{help && <p className={classNames.help || "mt-2 text-sm text-gray-500"}>{help}</p>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React, { FC, useContext } from 'react';
|
||||
import { setSubmissionValue } from '../../lib/elements';
|
||||
import { classNamesConcat } from '../../lib/utils';
|
||||
import { ClassNames } from '../../types';
|
||||
import { SubmissionContext } from '../SnoopForm/SnoopForm';
|
||||
import { PageContext } from '../SnoopPage/SnoopPage';
|
||||
import React, { FC, useContext } from "react";
|
||||
import { setSubmissionValue } from "../../lib/elements";
|
||||
import { classNamesConcat } from "../../lib/utils";
|
||||
import { ClassNames } from "../../types";
|
||||
import { SubmissionContext } from "../SnoopForm/SnoopForm";
|
||||
import { PageContext } from "../SnoopPage/SnoopPage";
|
||||
|
||||
interface Props {
|
||||
name: string;
|
||||
@@ -15,62 +15,41 @@ interface Props {
|
||||
required: boolean;
|
||||
}
|
||||
|
||||
export const Email: FC<Props> = ({
|
||||
name,
|
||||
label,
|
||||
help,
|
||||
Icon,
|
||||
classNames,
|
||||
placeholder,
|
||||
required,
|
||||
}) => {
|
||||
export const Email: FC<Props> = ({ name, label, help, Icon, classNames, placeholder, required }) => {
|
||||
const { setSubmission } = useContext(SubmissionContext);
|
||||
const pageName = useContext(PageContext);
|
||||
return (
|
||||
<div>
|
||||
{label && (
|
||||
<label
|
||||
htmlFor={name}
|
||||
className={
|
||||
classNames.label || 'block text-sm font-medium text-gray-700'
|
||||
}
|
||||
>
|
||||
<label htmlFor={name} className={classNames.label || "block text-sm font-medium text-gray-700"}>
|
||||
{label}
|
||||
</label>
|
||||
)}
|
||||
<div className="relative mt-1 rounded-md shadow-sm">
|
||||
{Icon && (
|
||||
<div className="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
|
||||
<div className="w-5 h-5 text-gray-400 ">{Icon}</div>
|
||||
<div className="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
|
||||
<div className="h-5 w-5 text-gray-400 ">{Icon}</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<input
|
||||
type="email"
|
||||
pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$"
|
||||
onInvalid={(e: any) =>
|
||||
e.target.setCustomValidity('please enter a valid email address')
|
||||
}
|
||||
onInput={(e: any) => e.target.setCustomValidity('')}
|
||||
onInvalid={(e: any) => e.target.setCustomValidity("please enter a valid email address")}
|
||||
onInput={(e: any) => e.target.setCustomValidity("")}
|
||||
name={name}
|
||||
id={`input-${name}`}
|
||||
className={classNamesConcat(
|
||||
Icon ? 'pl-10' : '',
|
||||
Icon ? "pl-10" : "",
|
||||
classNames.element ||
|
||||
'block w-full border-gray-300 rounded-md focus:ring-slate-500 focus:border-slate-500 sm:text-sm'
|
||||
"block w-full rounded-md border-gray-300 focus:border-slate-500 focus:ring-slate-500 sm:text-sm"
|
||||
)}
|
||||
placeholder={placeholder}
|
||||
onChange={(e) =>
|
||||
setSubmissionValue(e.target.value, pageName, name, setSubmission)
|
||||
}
|
||||
onChange={(e) => setSubmissionValue(e.target.value, pageName, name, setSubmission)}
|
||||
required={required}
|
||||
/>
|
||||
</div>
|
||||
{help && (
|
||||
<p className={classNames.help || 'mt-2 text-sm text-gray-500'}>
|
||||
{help}
|
||||
</p>
|
||||
)}
|
||||
{help && <p className={classNames.help || "mt-2 text-sm text-gray-500"}>{help}</p>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React, { FC, useContext } from 'react';
|
||||
import { setSubmissionValue } from '../../lib/elements';
|
||||
import { classNamesConcat } from '../../lib/utils';
|
||||
import { ClassNames } from '../../types';
|
||||
import { SubmissionContext } from '../SnoopForm/SnoopForm';
|
||||
import { PageContext } from '../SnoopPage/SnoopPage';
|
||||
import React, { FC, useContext } from "react";
|
||||
import { setSubmissionValue } from "../../lib/elements";
|
||||
import { classNamesConcat } from "../../lib/utils";
|
||||
import { ClassNames } from "../../types";
|
||||
import { SubmissionContext } from "../SnoopForm/SnoopForm";
|
||||
import { PageContext } from "../SnoopPage/SnoopPage";
|
||||
|
||||
interface Props {
|
||||
name: string;
|
||||
@@ -15,33 +15,20 @@ interface Props {
|
||||
required: boolean;
|
||||
}
|
||||
|
||||
export const Number: FC<Props> = ({
|
||||
name,
|
||||
label,
|
||||
help,
|
||||
Icon,
|
||||
classNames,
|
||||
placeholder,
|
||||
required,
|
||||
}) => {
|
||||
export const Number: FC<Props> = ({ name, label, help, Icon, classNames, placeholder, required }) => {
|
||||
const { setSubmission } = useContext(SubmissionContext);
|
||||
const pageName = useContext(PageContext);
|
||||
return (
|
||||
<div>
|
||||
{label && (
|
||||
<label
|
||||
htmlFor={name}
|
||||
className={
|
||||
classNames.label || 'block text-sm font-medium text-gray-700'
|
||||
}
|
||||
>
|
||||
<label htmlFor={name} className={classNames.label || "block text-sm font-medium text-gray-700"}>
|
||||
{label}
|
||||
</label>
|
||||
)}
|
||||
<div className="relative mt-1 rounded-md shadow-sm">
|
||||
{Icon && (
|
||||
<div className="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
|
||||
<div className="w-5 h-5 text-gray-400 ">{Icon}</div>
|
||||
<div className="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
|
||||
<div className="h-5 w-5 text-gray-400 ">{Icon}</div>
|
||||
</div>
|
||||
)}
|
||||
<input
|
||||
@@ -49,22 +36,16 @@ export const Number: FC<Props> = ({
|
||||
name={name}
|
||||
id={`input-${name}`}
|
||||
className={classNamesConcat(
|
||||
Icon ? 'pl-10' : '',
|
||||
Icon ? "pl-10" : "",
|
||||
classNames.element ||
|
||||
'block w-full border-gray-300 rounded-md focus:ring-slate-500 focus:border-slate-500 sm:text-sm'
|
||||
"block w-full rounded-md border-gray-300 focus:border-slate-500 focus:ring-slate-500 sm:text-sm"
|
||||
)}
|
||||
placeholder={placeholder}
|
||||
onChange={(e) =>
|
||||
setSubmissionValue(e.target.value, pageName, name, setSubmission)
|
||||
}
|
||||
onChange={(e) => setSubmissionValue(e.target.value, pageName, name, setSubmission)}
|
||||
required={required}
|
||||
/>
|
||||
</div>
|
||||
{help && (
|
||||
<p className={classNames.help || 'mt-2 text-sm text-gray-500'}>
|
||||
{help}
|
||||
</p>
|
||||
)}
|
||||
{help && <p className={classNames.help || "mt-2 text-sm text-gray-500"}>{help}</p>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React, { FC, useContext } from 'react';
|
||||
import { setSubmissionValue } from '../../lib/elements';
|
||||
import { classNamesConcat } from '../../lib/utils';
|
||||
import { ClassNames } from '../../types';
|
||||
import { SubmissionContext } from '../SnoopForm/SnoopForm';
|
||||
import { PageContext } from '../SnoopPage/SnoopPage';
|
||||
import React, { FC, useContext } from "react";
|
||||
import { setSubmissionValue } from "../../lib/elements";
|
||||
import { classNamesConcat } from "../../lib/utils";
|
||||
import { ClassNames } from "../../types";
|
||||
import { SubmissionContext } from "../SnoopForm/SnoopForm";
|
||||
import { PageContext } from "../SnoopPage/SnoopPage";
|
||||
|
||||
interface Props {
|
||||
name: string;
|
||||
@@ -15,33 +15,20 @@ interface Props {
|
||||
required: boolean;
|
||||
}
|
||||
|
||||
export const Phone: FC<Props> = ({
|
||||
name,
|
||||
label,
|
||||
help,
|
||||
Icon,
|
||||
classNames,
|
||||
placeholder,
|
||||
required,
|
||||
}) => {
|
||||
export const Phone: FC<Props> = ({ name, label, help, Icon, classNames, placeholder, required }) => {
|
||||
const { setSubmission } = useContext(SubmissionContext);
|
||||
const pageName = useContext(PageContext);
|
||||
return (
|
||||
<div>
|
||||
{label && (
|
||||
<label
|
||||
htmlFor={name}
|
||||
className={
|
||||
classNames.label || 'block text-sm font-medium text-gray-700'
|
||||
}
|
||||
>
|
||||
<label htmlFor={name} className={classNames.label || "block text-sm font-medium text-gray-700"}>
|
||||
{label}
|
||||
</label>
|
||||
)}
|
||||
<div className="relative mt-1 rounded-md shadow-sm">
|
||||
{Icon && (
|
||||
<div className="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
|
||||
<div className="w-5 h-5 text-gray-400 ">{Icon}</div>
|
||||
<div className="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
|
||||
<div className="h-5 w-5 text-gray-400 ">{Icon}</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -50,22 +37,16 @@ export const Phone: FC<Props> = ({
|
||||
name={name}
|
||||
id={`input-${name}`}
|
||||
className={classNamesConcat(
|
||||
Icon ? 'pl-10' : '',
|
||||
Icon ? "pl-10" : "",
|
||||
classNames.element ||
|
||||
'block w-full border-gray-300 rounded-md focus:ring-slate-500 focus:border-slate-500 sm:text-sm'
|
||||
"block w-full rounded-md border-gray-300 focus:border-slate-500 focus:ring-slate-500 sm:text-sm"
|
||||
)}
|
||||
placeholder={placeholder}
|
||||
onChange={(e) =>
|
||||
setSubmissionValue(e.target.value, pageName, name, setSubmission)
|
||||
}
|
||||
onChange={(e) => setSubmissionValue(e.target.value, pageName, name, setSubmission)}
|
||||
required={required}
|
||||
/>
|
||||
</div>
|
||||
{help && (
|
||||
<p className={classNames.help || 'mt-2 text-sm text-gray-500'}>
|
||||
{help}
|
||||
</p>
|
||||
)}
|
||||
{help && <p className={classNames.help || "mt-2 text-sm text-gray-500"}>{help}</p>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React, { FC, useContext } from 'react';
|
||||
import { getOptionValue, setSubmissionValue } from '../../lib/elements';
|
||||
import { ClassNames, Option } from '../../types';
|
||||
import { SubmissionContext } from '../SnoopForm/SnoopForm';
|
||||
import { PageContext } from '../SnoopPage/SnoopPage';
|
||||
import React, { FC, useContext } from "react";
|
||||
import { getOptionValue, setSubmissionValue } from "../../lib/elements";
|
||||
import { ClassNames, Option } from "../../types";
|
||||
import { SubmissionContext } from "../SnoopForm/SnoopForm";
|
||||
import { PageContext } from "../SnoopPage/SnoopPage";
|
||||
|
||||
interface Props {
|
||||
name: string;
|
||||
@@ -14,26 +14,14 @@ interface Props {
|
||||
required?: boolean;
|
||||
}
|
||||
|
||||
export const Radio: FC<Props> = ({
|
||||
name,
|
||||
label,
|
||||
help,
|
||||
options,
|
||||
classNames,
|
||||
}) => {
|
||||
export const Radio: FC<Props> = ({ name, label, help, options, classNames }) => {
|
||||
const { setSubmission }: any = useContext(SubmissionContext);
|
||||
const pageName = useContext(PageContext);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{label && (
|
||||
<label
|
||||
className={
|
||||
classNames.label || 'block text-sm font-medium text-gray-700'
|
||||
}
|
||||
>
|
||||
{label}
|
||||
</label>
|
||||
<label className={classNames.label || "block text-sm font-medium text-gray-700"}>{label}</label>
|
||||
)}
|
||||
<fieldset className="mt-2">
|
||||
<legend className="sr-only">Please choose an option</legend>
|
||||
@@ -45,38 +33,20 @@ export const Radio: FC<Props> = ({
|
||||
name={name}
|
||||
type="radio"
|
||||
className={
|
||||
classNames.element ||
|
||||
'focus:ring-slate-500 h-4 w-4 text-slate-600 border-gray-300'
|
||||
}
|
||||
onClick={() =>
|
||||
setSubmissionValue(
|
||||
getOptionValue(option),
|
||||
pageName,
|
||||
name,
|
||||
setSubmission
|
||||
)
|
||||
classNames.element || "h-4 w-4 border-gray-300 text-slate-600 focus:ring-slate-500"
|
||||
}
|
||||
onClick={() => setSubmissionValue(getOptionValue(option), pageName, name, setSubmission)}
|
||||
/>
|
||||
<label
|
||||
htmlFor={`${name}-${
|
||||
typeof option === 'object' ? option.value : option
|
||||
}`}
|
||||
className={
|
||||
classNames.elementLabel ||
|
||||
'block ml-3 text-base font-medium text-gray-700'
|
||||
}
|
||||
>
|
||||
{typeof option === 'object' ? option.label : option}
|
||||
htmlFor={`${name}-${typeof option === "object" ? option.value : option}`}
|
||||
className={classNames.elementLabel || "ml-3 block text-base font-medium text-gray-700"}>
|
||||
{typeof option === "object" ? option.label : option}
|
||||
</label>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</fieldset>
|
||||
{help && (
|
||||
<p className={classNames.help || 'mt-2 text-sm text-gray-500'}>
|
||||
{help}
|
||||
</p>
|
||||
)}
|
||||
{help && <p className={classNames.help || "mt-2 text-sm text-gray-500"}>{help}</p>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { FC } from 'react';
|
||||
import { classNamesConcat } from '../../lib/utils';
|
||||
import { ClassNames } from '../../types';
|
||||
import React, { FC } from "react";
|
||||
import { classNamesConcat } from "../../lib/utils";
|
||||
import { ClassNames } from "../../types";
|
||||
|
||||
interface Props {
|
||||
label?: string;
|
||||
@@ -13,10 +13,9 @@ export const Submit: FC<Props> = ({ classNames, label }) => {
|
||||
type="submit"
|
||||
className={classNamesConcat(
|
||||
classNames?.button ||
|
||||
'inline-flex items-center px-3 py-2 text-sm font-medium leading-4 text-white border border-transparent rounded-md shadow-sm bg-slate-600 hover:bg-slate-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-slate-500'
|
||||
)}
|
||||
>
|
||||
{label || 'Submit'}
|
||||
"inline-flex items-center rounded-md border border-transparent bg-slate-600 px-3 py-2 text-sm font-medium leading-4 text-white shadow-sm hover:bg-slate-700 focus:outline-none focus:ring-2 focus:ring-slate-500 focus:ring-offset-2"
|
||||
)}>
|
||||
{label || "Submit"}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React, { FC, useContext } from 'react';
|
||||
import { setSubmissionValue } from '../../lib/elements';
|
||||
import { classNamesConcat } from '../../lib/utils';
|
||||
import { ClassNames } from '../../types';
|
||||
import { SubmissionContext } from '../SnoopForm/SnoopForm';
|
||||
import { PageContext } from '../SnoopPage/SnoopPage';
|
||||
import React, { FC, useContext } from "react";
|
||||
import { setSubmissionValue } from "../../lib/elements";
|
||||
import { classNamesConcat } from "../../lib/utils";
|
||||
import { ClassNames } from "../../types";
|
||||
import { SubmissionContext } from "../SnoopForm/SnoopForm";
|
||||
import { PageContext } from "../SnoopPage/SnoopPage";
|
||||
|
||||
interface Props {
|
||||
name: string;
|
||||
@@ -15,33 +15,20 @@ interface Props {
|
||||
required: boolean;
|
||||
}
|
||||
|
||||
export const Text: FC<Props> = ({
|
||||
name,
|
||||
label,
|
||||
help,
|
||||
Icon,
|
||||
classNames,
|
||||
placeholder,
|
||||
required,
|
||||
}) => {
|
||||
export const Text: FC<Props> = ({ name, label, help, Icon, classNames, placeholder, required }) => {
|
||||
const { setSubmission } = useContext(SubmissionContext);
|
||||
const pageName = useContext(PageContext);
|
||||
return (
|
||||
<div>
|
||||
{label && (
|
||||
<label
|
||||
htmlFor={name}
|
||||
className={
|
||||
classNames.label || 'block text-sm font-medium text-gray-700'
|
||||
}
|
||||
>
|
||||
<label htmlFor={name} className={classNames.label || "block text-sm font-medium text-gray-700"}>
|
||||
{label}
|
||||
</label>
|
||||
)}
|
||||
<div className={'relative mt-1 rounded-md shadow-sm'}>
|
||||
<div className={"relative mt-1 rounded-md shadow-sm"}>
|
||||
{Icon && (
|
||||
<div className="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
|
||||
<div className="w-5 h-5 text-gray-400">{Icon}</div>
|
||||
<div className="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
|
||||
<div className="h-5 w-5 text-gray-400">{Icon}</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -50,22 +37,16 @@ export const Text: FC<Props> = ({
|
||||
name={name}
|
||||
id={`input-${name}`}
|
||||
className={classNamesConcat(
|
||||
Icon ? 'pl-10' : '',
|
||||
Icon ? "pl-10" : "",
|
||||
classNames.element ||
|
||||
'block w-full border-gray-300 rounded-md focus:ring-slate-500 focus:border-slate-500 sm:text-sm'
|
||||
"block w-full rounded-md border-gray-300 focus:border-slate-500 focus:ring-slate-500 sm:text-sm"
|
||||
)}
|
||||
placeholder={placeholder}
|
||||
onChange={(e) =>
|
||||
setSubmissionValue(e.target.value, pageName, name, setSubmission)
|
||||
}
|
||||
onChange={(e) => setSubmissionValue(e.target.value, pageName, name, setSubmission)}
|
||||
required={required}
|
||||
/>
|
||||
</div>
|
||||
{help && (
|
||||
<p className={classNames.help || 'mt-2 text-sm text-gray-500'}>
|
||||
{help}
|
||||
</p>
|
||||
)}
|
||||
{help && <p className={classNames.help || "mt-2 text-sm text-gray-500"}>{help}</p>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React, { FC, useContext } from 'react';
|
||||
import { setSubmissionValue } from '../../lib/elements';
|
||||
import { SubmissionContext } from '../SnoopForm/SnoopForm';
|
||||
import { PageContext } from '../SnoopPage/SnoopPage';
|
||||
import { ClassNames } from '../../types';
|
||||
import { classNamesConcat } from '../../lib/utils';
|
||||
import React, { FC, useContext } from "react";
|
||||
import { setSubmissionValue } from "../../lib/elements";
|
||||
import { SubmissionContext } from "../SnoopForm/SnoopForm";
|
||||
import { PageContext } from "../SnoopPage/SnoopPage";
|
||||
import { ClassNames } from "../../types";
|
||||
import { classNamesConcat } from "../../lib/utils";
|
||||
|
||||
interface Props {
|
||||
name: string;
|
||||
@@ -15,26 +15,13 @@ interface Props {
|
||||
required: boolean;
|
||||
}
|
||||
|
||||
export const Textarea: FC<Props> = ({
|
||||
name,
|
||||
label,
|
||||
help,
|
||||
classNames,
|
||||
placeholder,
|
||||
rows,
|
||||
required,
|
||||
}) => {
|
||||
export const Textarea: FC<Props> = ({ name, label, help, classNames, placeholder, rows, required }) => {
|
||||
const { setSubmission } = useContext(SubmissionContext);
|
||||
const pageName = useContext(PageContext);
|
||||
return (
|
||||
<div>
|
||||
{label && (
|
||||
<label
|
||||
htmlFor={name}
|
||||
className={
|
||||
classNames.label || 'block text-sm font-medium text-gray-700'
|
||||
}
|
||||
>
|
||||
<label htmlFor={name} className={classNames.label || "block text-sm font-medium text-gray-700"}>
|
||||
{label}
|
||||
</label>
|
||||
)}
|
||||
@@ -44,21 +31,15 @@ export const Textarea: FC<Props> = ({
|
||||
name={name}
|
||||
id={`input-${name}`}
|
||||
className={classNamesConcat(
|
||||
'block w-full border border-gray-300 rounded-md shadow-sm focus:ring-slate-500 focus:border-slate-500 sm:text-sm',
|
||||
"block w-full rounded-md border border-gray-300 shadow-sm focus:border-slate-500 focus:ring-slate-500 sm:text-sm",
|
||||
classNames.element
|
||||
)}
|
||||
placeholder={placeholder}
|
||||
onChange={(e) =>
|
||||
setSubmissionValue(e.target.value, pageName, name, setSubmission)
|
||||
}
|
||||
onChange={(e) => setSubmissionValue(e.target.value, pageName, name, setSubmission)}
|
||||
required={required}
|
||||
/>
|
||||
</div>
|
||||
{help && (
|
||||
<p className={classNames.help || 'mt-2 text-sm text-gray-500'}>
|
||||
{help}
|
||||
</p>
|
||||
)}
|
||||
{help && <p className={classNames.help || "mt-2 text-sm text-gray-500"}>{help}</p>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React, { FC, useContext } from 'react';
|
||||
import { setSubmissionValue } from '../../lib/elements';
|
||||
import { classNamesConcat } from '../../lib/utils';
|
||||
import { ClassNames } from '../../types';
|
||||
import { SubmissionContext } from '../SnoopForm/SnoopForm';
|
||||
import { PageContext } from '../SnoopPage/SnoopPage';
|
||||
import React, { FC, useContext } from "react";
|
||||
import { setSubmissionValue } from "../../lib/elements";
|
||||
import { classNamesConcat } from "../../lib/utils";
|
||||
import { ClassNames } from "../../types";
|
||||
import { SubmissionContext } from "../SnoopForm/SnoopForm";
|
||||
import { PageContext } from "../SnoopPage/SnoopPage";
|
||||
|
||||
interface Props {
|
||||
name: string;
|
||||
@@ -15,62 +15,41 @@ interface Props {
|
||||
required: boolean;
|
||||
}
|
||||
|
||||
export const Website: FC<Props> = ({
|
||||
name,
|
||||
label,
|
||||
help,
|
||||
Icon,
|
||||
classNames,
|
||||
placeholder,
|
||||
required,
|
||||
}) => {
|
||||
export const Website: FC<Props> = ({ name, label, help, Icon, classNames, placeholder, required }) => {
|
||||
const { setSubmission } = useContext(SubmissionContext);
|
||||
const pageName = useContext(PageContext);
|
||||
return (
|
||||
<div>
|
||||
{label && (
|
||||
<label
|
||||
htmlFor={name}
|
||||
className={
|
||||
classNames.label || 'block text-sm font-medium text-gray-700'
|
||||
}
|
||||
>
|
||||
<label htmlFor={name} className={classNames.label || "block text-sm font-medium text-gray-700"}>
|
||||
{label}
|
||||
</label>
|
||||
)}
|
||||
<div className="relative mt-1 rounded-md shadow-sm">
|
||||
{Icon && (
|
||||
<div className="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
|
||||
<div className="w-5 h-5 text-gray-400 ">{Icon}</div>
|
||||
<div className="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
|
||||
<div className="h-5 w-5 text-gray-400 ">{Icon}</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<input
|
||||
type="url"
|
||||
pattern="https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)"
|
||||
onInvalid={(e: any) =>
|
||||
e.target.setCustomValidity('please provide a valid website address')
|
||||
}
|
||||
onInput={(e: any) => e.target.setCustomValidity('')}
|
||||
onInvalid={(e: any) => e.target.setCustomValidity("please provide a valid website address")}
|
||||
onInput={(e: any) => e.target.setCustomValidity("")}
|
||||
name={name}
|
||||
id={`input-${name}`}
|
||||
className={classNamesConcat(
|
||||
Icon ? 'pl-10' : '',
|
||||
Icon ? "pl-10" : "",
|
||||
classNames.element ||
|
||||
'block w-full border-gray-300 rounded-md focus:ring-slate-500 focus:border-slate-500 sm:text-sm'
|
||||
"block w-full rounded-md border-gray-300 focus:border-slate-500 focus:ring-slate-500 sm:text-sm"
|
||||
)}
|
||||
placeholder={placeholder}
|
||||
onChange={(e) =>
|
||||
setSubmissionValue(e.target.value, pageName, name, setSubmission)
|
||||
}
|
||||
onChange={(e) => setSubmissionValue(e.target.value, pageName, name, setSubmission)}
|
||||
required={required}
|
||||
/>
|
||||
</div>
|
||||
{help && (
|
||||
<p className={classNames.help || 'mt-2 text-sm text-gray-500'}>
|
||||
{help}
|
||||
</p>
|
||||
)}
|
||||
{help && <p className={classNames.help || "mt-2 text-sm text-gray-500"}>{help}</p>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { Meta, Story } from '@storybook/react';
|
||||
import React from 'react';
|
||||
import { SnoopElement, SnoopForm, SnoopPage } from '../src';
|
||||
import { SnoopElementProps } from '../src/components/SnoopElement/SnoopElement';
|
||||
import { Meta, Story } from "@storybook/react";
|
||||
import React from "react";
|
||||
import { SnoopElement, SnoopForm, SnoopPage } from "../src";
|
||||
import { SnoopElementProps } from "../src/components/SnoopElement/SnoopElement";
|
||||
|
||||
const meta: Meta = {
|
||||
title: 'Snoop/SnoopElement',
|
||||
title: "Snoop/SnoopElement",
|
||||
component: SnoopElement,
|
||||
argTypes: {
|
||||
type: {
|
||||
defaultValue: 'text',
|
||||
defaultValue: "text",
|
||||
},
|
||||
},
|
||||
parameters: {
|
||||
@@ -28,7 +28,7 @@ const Template: Story<SnoopElementProps> = (args) => (
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
type: 'text',
|
||||
name: 'myInput',
|
||||
type: "text",
|
||||
name: "myInput",
|
||||
options: [],
|
||||
};
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import React, { FC, useContext, useEffect } from 'react';
|
||||
import { getOptionsSchema } from '../../lib/elements';
|
||||
import { ClassNames } from '../../types';
|
||||
import { Cards } from '../Elements/Cards';
|
||||
import { Checkbox } from '../Elements/Checkbox';
|
||||
import { Email } from '../Elements/Email';
|
||||
import { Number } from '../Elements/Number';
|
||||
import { Phone } from '../Elements/Phone';
|
||||
import { Radio } from '../Elements/Radio';
|
||||
import { Submit } from '../Elements/Submit';
|
||||
import { Text } from '../Elements/Text';
|
||||
import { Textarea } from '../Elements/Textarea';
|
||||
import { Website } from '../Elements/Website';
|
||||
import { CurrentPageContext, SchemaContext } from '../SnoopForm/SnoopForm';
|
||||
import { PageContext } from '../SnoopPage/SnoopPage';
|
||||
import React, { FC, useContext, useEffect } from "react";
|
||||
import { getOptionsSchema } from "../../lib/elements";
|
||||
import { ClassNames } from "../../types";
|
||||
import { Cards } from "../Elements/Cards";
|
||||
import { Checkbox } from "../Elements/Checkbox";
|
||||
import { Email } from "../Elements/Email";
|
||||
import { Number } from "../Elements/Number";
|
||||
import { Phone } from "../Elements/Phone";
|
||||
import { Radio } from "../Elements/Radio";
|
||||
import { Submit } from "../Elements/Submit";
|
||||
import { Text } from "../Elements/Text";
|
||||
import { Textarea } from "../Elements/Textarea";
|
||||
import { Website } from "../Elements/Website";
|
||||
import { CurrentPageContext, SchemaContext } from "../SnoopForm/SnoopForm";
|
||||
import { PageContext } from "../SnoopPage/SnoopPage";
|
||||
|
||||
interface Option {
|
||||
label: string;
|
||||
@@ -54,10 +54,8 @@ export const SnoopElement: FC<SnoopElementProps> = ({
|
||||
|
||||
useEffect(() => {
|
||||
setSchema((schema: any) => {
|
||||
if (pageName === '') {
|
||||
console.warn(
|
||||
`🦝 SnoopForms: An Element must always be a child of a page!`
|
||||
);
|
||||
if (pageName === "") {
|
||||
console.warn(`🦝 SnoopForms: An Element must always be a child of a page!`);
|
||||
return;
|
||||
}
|
||||
const newSchema = { ...schema };
|
||||
@@ -66,9 +64,7 @@ export const SnoopElement: FC<SnoopElementProps> = ({
|
||||
console.warn(`🦝 SnoopForms: Error accessing page`);
|
||||
return;
|
||||
}
|
||||
let elementIdx = newSchema.pages[pageIdx].elements.findIndex(
|
||||
(e: any) => e.name === name
|
||||
);
|
||||
let elementIdx = newSchema.pages[pageIdx].elements.findIndex((e: any) => e.name === name);
|
||||
if (elementIdx === -1) {
|
||||
newSchema.pages[pageIdx].elements.push({ name });
|
||||
elementIdx = newSchema.pages[pageIdx].elements.length - 1;
|
||||
@@ -76,9 +72,8 @@ export const SnoopElement: FC<SnoopElementProps> = ({
|
||||
newSchema.pages[pageIdx].elements[elementIdx].type = type;
|
||||
newSchema.pages[pageIdx].elements[elementIdx].label = label;
|
||||
newSchema.pages[pageIdx].elements[elementIdx].help = help;
|
||||
if (['checkbox', 'radio'].includes(type)) {
|
||||
newSchema.pages[pageIdx].elements[elementIdx].options =
|
||||
getOptionsSchema(options);
|
||||
if (["checkbox", "radio"].includes(type)) {
|
||||
newSchema.pages[pageIdx].elements[elementIdx].options = getOptionsSchema(options);
|
||||
}
|
||||
return newSchema;
|
||||
});
|
||||
@@ -86,10 +81,9 @@ export const SnoopElement: FC<SnoopElementProps> = ({
|
||||
|
||||
return (
|
||||
<div>
|
||||
{currentPageIdx ===
|
||||
schema.pages.findIndex((p: any) => p.name === pageName) && (
|
||||
{currentPageIdx === schema.pages.findIndex((p: any) => p.name === pageName) && (
|
||||
<div>
|
||||
{type === 'cards' ? (
|
||||
{type === "cards" ? (
|
||||
<Cards
|
||||
name={name}
|
||||
label={label}
|
||||
@@ -100,7 +94,7 @@ export const SnoopElement: FC<SnoopElementProps> = ({
|
||||
options={options || []}
|
||||
autoSubmit={autoSubmit}
|
||||
/>
|
||||
) : type === 'checkbox' ? (
|
||||
) : type === "checkbox" ? (
|
||||
<Checkbox
|
||||
name={name}
|
||||
label={label}
|
||||
@@ -109,7 +103,7 @@ export const SnoopElement: FC<SnoopElementProps> = ({
|
||||
required={required}
|
||||
options={options || []}
|
||||
/>
|
||||
) : type === 'email' ? (
|
||||
) : type === "email" ? (
|
||||
<Email
|
||||
name={name}
|
||||
label={label}
|
||||
@@ -119,7 +113,7 @@ export const SnoopElement: FC<SnoopElementProps> = ({
|
||||
classNames={classNames}
|
||||
required={required}
|
||||
/>
|
||||
) : type === 'number' ? (
|
||||
) : type === "number" ? (
|
||||
<Number
|
||||
name={name}
|
||||
label={label}
|
||||
@@ -129,7 +123,7 @@ export const SnoopElement: FC<SnoopElementProps> = ({
|
||||
classNames={classNames}
|
||||
required={required}
|
||||
/>
|
||||
) : type === 'phone' ? (
|
||||
) : type === "phone" ? (
|
||||
<Phone
|
||||
name={name}
|
||||
label={label}
|
||||
@@ -139,7 +133,7 @@ export const SnoopElement: FC<SnoopElementProps> = ({
|
||||
classNames={classNames}
|
||||
required={required}
|
||||
/>
|
||||
) : type === 'radio' ? (
|
||||
) : type === "radio" ? (
|
||||
<Radio
|
||||
name={name}
|
||||
label={label}
|
||||
@@ -148,9 +142,9 @@ export const SnoopElement: FC<SnoopElementProps> = ({
|
||||
required={required}
|
||||
options={options || []}
|
||||
/>
|
||||
) : type === 'submit' ? (
|
||||
) : type === "submit" ? (
|
||||
<Submit label={label} classNames={classNames} />
|
||||
) : type === 'text' ? (
|
||||
) : type === "text" ? (
|
||||
<Text
|
||||
name={name}
|
||||
label={label}
|
||||
@@ -160,7 +154,7 @@ export const SnoopElement: FC<SnoopElementProps> = ({
|
||||
classNames={classNames}
|
||||
required={required}
|
||||
/>
|
||||
) : type === 'textarea' ? (
|
||||
) : type === "textarea" ? (
|
||||
<Textarea
|
||||
name={name}
|
||||
label={label}
|
||||
@@ -170,7 +164,7 @@ export const SnoopElement: FC<SnoopElementProps> = ({
|
||||
classNames={classNames}
|
||||
required={required}
|
||||
/>
|
||||
) : type === 'website' ? (
|
||||
) : type === "website" ? (
|
||||
<Website
|
||||
name={name}
|
||||
label={label}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { createContext, FC, ReactNode, useState } from 'react';
|
||||
import { classNamesConcat } from '../../lib/utils';
|
||||
import React, { createContext, FC, ReactNode, useState } from "react";
|
||||
import { classNamesConcat } from "../../lib/utils";
|
||||
|
||||
export const SchemaContext = createContext({
|
||||
schema: { pages: [] },
|
||||
@@ -34,7 +34,7 @@ interface onSubmitProps {
|
||||
interface Props {
|
||||
domain?: string;
|
||||
formId?: string;
|
||||
protocol?: 'http' | 'https';
|
||||
protocol?: "http" | "https";
|
||||
localOnly?: boolean;
|
||||
className?: string;
|
||||
onSubmit?: (obj: onSubmitProps) => void;
|
||||
@@ -42,18 +42,18 @@ interface Props {
|
||||
}
|
||||
|
||||
export const SnoopForm: FC<Props> = ({
|
||||
domain = 'app.snoopforms.com',
|
||||
domain = "app.snoopforms.com",
|
||||
formId,
|
||||
protocol = 'https',
|
||||
protocol = "https",
|
||||
localOnly = false,
|
||||
className = '',
|
||||
className = "",
|
||||
onSubmit = (): any => {},
|
||||
children,
|
||||
}) => {
|
||||
const [schema, setSchema] = useState<any>({ pages: [] });
|
||||
const [submission, setSubmission] = useState<any>({});
|
||||
const [currentPageIdx, setCurrentPageIdx] = useState(0);
|
||||
const [submissionSessionId, setSubmissionSessionId] = useState('');
|
||||
const [submissionSessionId, setSubmissionSessionId] = useState("");
|
||||
|
||||
const handleSubmit = async (pageName: string) => {
|
||||
let _submissionSessionId = submissionSessionId;
|
||||
@@ -61,9 +61,7 @@ export const SnoopForm: FC<Props> = ({
|
||||
// create answer session if it don't exist
|
||||
try {
|
||||
if (!formId) {
|
||||
console.warn(
|
||||
`🦝 SnoopForms: formId not set. Skipping sending submission to snoopHub.`
|
||||
);
|
||||
console.warn(`🦝 SnoopForms: formId not set. Skipping sending submission to snoopHub.`);
|
||||
return;
|
||||
}
|
||||
if (!_submissionSessionId) {
|
||||
@@ -72,8 +70,8 @@ export const SnoopForm: FC<Props> = ({
|
||||
const submissionSessionRes: any = await fetch(
|
||||
`${protocol}://${domain}/api/forms/${formId}/submissionSessions`,
|
||||
{
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({}),
|
||||
}
|
||||
);
|
||||
@@ -83,12 +81,12 @@ export const SnoopForm: FC<Props> = ({
|
||||
}
|
||||
// send answer to snoop platform
|
||||
await fetch(`${protocol}://${domain}/api/forms/${formId}/event`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
events: [
|
||||
{
|
||||
type: 'pageSubmission',
|
||||
type: "pageSubmission",
|
||||
data: {
|
||||
pageName,
|
||||
submissionSessionId: _submissionSessionId,
|
||||
@@ -97,18 +95,16 @@ export const SnoopForm: FC<Props> = ({
|
||||
},
|
||||
// update schema
|
||||
// TODO: do conditionally only when requested by the snoopHub
|
||||
{ type: 'updateSchema', data: schema },
|
||||
{ type: "updateSchema", data: schema },
|
||||
],
|
||||
}),
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(
|
||||
`🦝 SnoopForms: Unable to send submission to snoopHub. Error: ${e}`
|
||||
);
|
||||
console.error(`🦝 SnoopForms: Unable to send submission to snoopHub. Error: ${e}`);
|
||||
}
|
||||
}
|
||||
const maxPageIdx = schema.pages.length - 1;
|
||||
const hasThankYou = schema.pages[maxPageIdx].type === 'thankyou';
|
||||
const hasThankYou = schema.pages[maxPageIdx].type === "thankyou";
|
||||
if (currentPageIdx < maxPageIdx) {
|
||||
setCurrentPageIdx(currentPageIdx + 1);
|
||||
}
|
||||
@@ -124,12 +120,8 @@ export const SnoopForm: FC<Props> = ({
|
||||
<SubmitHandlerContext.Provider value={handleSubmit}>
|
||||
<SchemaContext.Provider value={{ schema, setSchema }}>
|
||||
<SubmissionContext.Provider value={{ submission, setSubmission }}>
|
||||
<CurrentPageContext.Provider
|
||||
value={{ currentPageIdx, setCurrentPageIdx }}
|
||||
>
|
||||
<div className={classNamesConcat('max-w-lg', className)}>
|
||||
{children}
|
||||
</div>
|
||||
<CurrentPageContext.Provider value={{ currentPageIdx, setCurrentPageIdx }}>
|
||||
<div className={classNamesConcat("max-w-lg", className)}>{children}</div>
|
||||
</CurrentPageContext.Provider>
|
||||
</SubmissionContext.Provider>
|
||||
</SchemaContext.Provider>
|
||||
|
||||
@@ -1,19 +1,8 @@
|
||||
import React, {
|
||||
createContext,
|
||||
FC,
|
||||
ReactNode,
|
||||
useContext,
|
||||
useEffect,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { classNamesConcat } from '../../lib/utils';
|
||||
import {
|
||||
CurrentPageContext,
|
||||
SchemaContext,
|
||||
SubmitHandlerContext,
|
||||
} from '../SnoopForm/SnoopForm';
|
||||
import React, { createContext, FC, ReactNode, useContext, useEffect, useState } from "react";
|
||||
import { classNamesConcat } from "../../lib/utils";
|
||||
import { CurrentPageContext, SchemaContext, SubmitHandlerContext } from "../SnoopForm/SnoopForm";
|
||||
|
||||
export const PageContext = createContext('');
|
||||
export const PageContext = createContext("");
|
||||
|
||||
interface Props {
|
||||
name: string;
|
||||
@@ -22,12 +11,7 @@ interface Props {
|
||||
thankyou?: boolean;
|
||||
}
|
||||
|
||||
export const SnoopPage: FC<Props> = ({
|
||||
name,
|
||||
className,
|
||||
children,
|
||||
thankyou = false,
|
||||
}) => {
|
||||
export const SnoopPage: FC<Props> = ({ name, className, children, thankyou = false }) => {
|
||||
const { schema, setSchema } = useContext<any>(SchemaContext);
|
||||
const handleSubmit = useContext(SubmitHandlerContext);
|
||||
const [initializing, setInitializing] = useState(true);
|
||||
@@ -38,14 +22,12 @@ export const SnoopPage: FC<Props> = ({
|
||||
const newSchema = { ...schema };
|
||||
let pageIdx = newSchema.pages.findIndex((p: any) => p.name === name);
|
||||
if (pageIdx !== -1) {
|
||||
console.warn(
|
||||
`🦝 SnoopForms: Page with the name "${name}" already exists`
|
||||
);
|
||||
console.warn(`🦝 SnoopForms: Page with the name "${name}" already exists`);
|
||||
return newSchema;
|
||||
}
|
||||
newSchema.pages.push({
|
||||
name,
|
||||
type: thankyou ? 'thankyou' : 'form',
|
||||
type: thankyou ? "thankyou" : "form",
|
||||
elements: [],
|
||||
});
|
||||
|
||||
@@ -74,8 +56,7 @@ export const SnoopPage: FC<Props> = ({
|
||||
if (thankyou) {
|
||||
return (
|
||||
<PageContext.Provider value={name}>
|
||||
{currentPageIdx ===
|
||||
schema.pages.findIndex((p: any) => p.name === name) && children}
|
||||
{currentPageIdx === schema.pages.findIndex((p: any) => p.name === name) && children}
|
||||
</PageContext.Provider>
|
||||
);
|
||||
} else {
|
||||
@@ -83,15 +64,11 @@ export const SnoopPage: FC<Props> = ({
|
||||
<PageContext.Provider value={name}>
|
||||
<form
|
||||
className={classNamesConcat(
|
||||
currentPageIdx ===
|
||||
schema.pages.findIndex((p: any) => p.name === name)
|
||||
? 'block'
|
||||
: 'hidden',
|
||||
'space-y-6',
|
||||
currentPageIdx === schema.pages.findIndex((p: any) => p.name === name) ? "block" : "hidden",
|
||||
"space-y-6",
|
||||
className
|
||||
)}
|
||||
onSubmit={onSubmit}
|
||||
>
|
||||
onSubmit={onSubmit}>
|
||||
{children}
|
||||
</form>
|
||||
</PageContext.Provider>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export * from './components/SnoopForm/SnoopForm';
|
||||
export * from './components/SnoopElement/SnoopElement';
|
||||
export * from './components/SnoopPage/SnoopPage';
|
||||
export * from "./components/SnoopForm/SnoopForm";
|
||||
export * from "./components/SnoopElement/SnoopElement";
|
||||
export * from "./components/SnoopPage/SnoopPage";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Option } from '../types';
|
||||
import { Option } from "../types";
|
||||
|
||||
export const setSubmissionValue = (
|
||||
v: any,
|
||||
@@ -20,14 +20,10 @@ export const getOptionsSchema = (options: any[] | undefined) => {
|
||||
const newOptions = [];
|
||||
if (options) {
|
||||
for (const option of options) {
|
||||
if (typeof option === 'string') {
|
||||
if (typeof option === "string") {
|
||||
newOptions.push({ label: option, value: option });
|
||||
}
|
||||
if (
|
||||
typeof option === 'object' &&
|
||||
'value' in option &&
|
||||
'label' in option
|
||||
) {
|
||||
if (typeof option === "object" && "value" in option && "label" in option) {
|
||||
newOptions.push({ label: option.label, value: option.value });
|
||||
}
|
||||
}
|
||||
@@ -36,5 +32,5 @@ export const getOptionsSchema = (options: any[] | undefined) => {
|
||||
};
|
||||
|
||||
export function getOptionValue(option: string | Option) {
|
||||
return typeof option === 'object' ? option.value : option;
|
||||
return typeof option === "object" ? option.value : option;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export const classNamesConcat = (...classes: any) => {
|
||||
return classes.filter(Boolean).join(' ');
|
||||
return classes.filter(Boolean).join(" ");
|
||||
};
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
{
|
||||
"name": "@formbricks/tailwind-config",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"main": "index.js",
|
||||
"devDependencies": {
|
||||
"@tailwindcss/forms": "^0.5.3",
|
||||
"tailwindcss": "^3.1.8"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
{
|
||||
"name": "@formbricks/tsconfig",
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
"private": true,
|
||||
"license": "MIT"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"name": "@formbricks/ui",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
@@ -25,8 +26,5 @@
|
||||
"@formbricks/tsconfig": "workspace:*",
|
||||
"tsup": "^6.1.3",
|
||||
"typescript": "^4.5.2"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user