apply prettier in react lib, make packages private

This commit is contained in:
Matthias Nannt
2022-10-18 13:41:48 +02:00
parent d5b5fd8dd9
commit 3e63e536e0
24 changed files with 242 additions and 506 deletions

View File

@@ -1,6 +1,7 @@
{
"name": "@formbricks/database",
"version": "1.0.0",
"private": true,
"license": "MIT",
"main": "./dist/index.js",
"module": "./dist/index.mjs",

View File

@@ -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"
}
}

View File

@@ -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"

View File

@@ -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>

View File

@@ -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>
);
};

View File

@@ -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>
);
};

View File

@@ -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>
);
};

View File

@@ -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>
);
};

View File

@@ -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>
);
};

View File

@@ -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>
);
};

View File

@@ -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>
);
};

View File

@@ -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>
);
};

View File

@@ -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>
);
};

View File

@@ -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>
);
};

View File

@@ -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: [],
};

View File

@@ -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}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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";

View File

@@ -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;
}

View File

@@ -1,3 +1,3 @@
export const classNamesConcat = (...classes: any) => {
return classes.filter(Boolean).join(' ');
return classes.filter(Boolean).join(" ");
};

View File

@@ -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"
}
}

View File

@@ -1,8 +1,6 @@
{
"name": "@formbricks/tsconfig",
"version": "1.0.0",
"license": "MIT",
"publishConfig": {
"access": "public"
}
"private": true,
"license": "MIT"
}

View File

@@ -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"
}
}