mirror of
https://github.com/formbricks/formbricks.git
synced 2026-01-25 18:48:58 -06:00
refactor radio buttons, add checkbox input type to react lib
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
export * from "./inputs/Button";
|
||||
export * from "./inputs/Checkbox";
|
||||
export * from "./inputs/Radio";
|
||||
export * from "./inputs/Submit";
|
||||
export * from "./inputs/Text";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import clsx from "clsx";
|
||||
import React, { useMemo } from "react";
|
||||
import { getElementId } from "../../lib/element";
|
||||
import { useEffectUpdateSchema } from "../../lib/schema";
|
||||
|
||||
90
packages/react/src/components/inputs/Checkbox.tsx
Normal file
90
packages/react/src/components/inputs/Checkbox.tsx
Normal file
@@ -0,0 +1,90 @@
|
||||
import clsx from "clsx";
|
||||
import React, { useMemo } from "react";
|
||||
import { useFormContext } from "react-hook-form";
|
||||
import { getElementId } from "../../lib/element";
|
||||
import { normalizeOptions } from "../../lib/options";
|
||||
import { useEffectUpdateSchema } from "../../lib/schema";
|
||||
import { getValidationRules } from "../../lib/validation";
|
||||
import { NameRequired, OptionsArray, OptionsObjectArray, UniversalInputProps } from "../../types";
|
||||
import { Fieldset } from "../shared/Fieldset";
|
||||
import { Help } from "../shared/Help";
|
||||
import { Inner } from "../shared/Inner";
|
||||
import { Label } from "../shared/Label";
|
||||
import { Legend } from "../shared/Legend";
|
||||
import { Messages } from "../shared/Messages";
|
||||
import { Option } from "../shared/Option";
|
||||
import { Options } from "../shared/Options";
|
||||
import { Outer } from "../shared/Outer";
|
||||
import { Wrapper } from "../shared/Wrapper";
|
||||
|
||||
interface CheckboxInputUniqueProps {
|
||||
options?: OptionsArray | OptionsObjectArray;
|
||||
fieldsetClassName?: string;
|
||||
legendClassName?: string;
|
||||
optionsClassName?: string;
|
||||
optionClassName?: string;
|
||||
}
|
||||
|
||||
type FormbricksProps = CheckboxInputUniqueProps & UniversalInputProps & NameRequired;
|
||||
|
||||
const inputType = "checkbox";
|
||||
|
||||
export function Checkbox(props: FormbricksProps) {
|
||||
const elemId = useMemo(() => getElementId(props.id, props.name), [props.id, props.name]);
|
||||
const options = useMemo(() => normalizeOptions(props.options), [props.options]);
|
||||
useEffectUpdateSchema(props, inputType);
|
||||
|
||||
const { register } = useFormContext();
|
||||
const validationRules = getValidationRules(props.validation);
|
||||
|
||||
if (!options || options.length === 0) {
|
||||
return (
|
||||
<Outer inputType={inputType} outerClassName={props.outerClassName}>
|
||||
<Wrapper wrapperClassName={props.wrapperClassName}>
|
||||
<Inner innerClassName={props.innerClassName}>
|
||||
<input
|
||||
className={clsx("formbricks-input", props.inputClassName)}
|
||||
type="checkbox"
|
||||
id={elemId}
|
||||
{...register(props.name, {
|
||||
required: { value: "required" in validationRules, message: "This field is required" },
|
||||
})}
|
||||
/>
|
||||
<Label label={props.label} elemId={elemId} />
|
||||
</Inner>
|
||||
</Wrapper>
|
||||
<Help help={props.help} elemId={elemId} />
|
||||
<Messages {...props} />
|
||||
</Outer>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Outer inputType={inputType} outerClassName={props.outerClassName}>
|
||||
<Fieldset fieldsetClassName={props.fieldsetClassName} name={props.name}>
|
||||
<Legend legendClassName={props.legendClassName}>{props.label}</Legend>
|
||||
<Help help={props.help} elemId={elemId} />
|
||||
<Options optionsClassName={props.optionsClassName}>
|
||||
{options.map((option) => (
|
||||
<Option optionClassName={props.optionClassName}>
|
||||
<Wrapper wrapperClassName={props.wrapperClassName}>
|
||||
<Inner innerClassName={props.innerClassName}>
|
||||
<input
|
||||
className={clsx("formbricks-input", props.inputClassName)}
|
||||
type="checkbox"
|
||||
id={`${props.name}-${option.value}`}
|
||||
value={option.value}
|
||||
disabled={option?.config?.disabled}
|
||||
{...register(props.name)}
|
||||
/>
|
||||
<Label label={option.label} elemId={`${props.name}-${option.value}`} />
|
||||
</Inner>
|
||||
</Wrapper>
|
||||
</Option>
|
||||
))}
|
||||
</Options>
|
||||
</Fieldset>
|
||||
<Messages {...props} />
|
||||
</Outer>
|
||||
);
|
||||
}
|
||||
@@ -6,15 +6,23 @@ import { normalizeOptions } from "../../lib/options";
|
||||
import { useEffectUpdateSchema } from "../../lib/schema";
|
||||
import { getValidationRules } from "../../lib/validation";
|
||||
import { NameRequired, OptionsArray, OptionsObjectArray, UniversalInputProps } from "../../types";
|
||||
import { Fieldset } from "../shared/Fieldset";
|
||||
import { Help } from "../shared/Help";
|
||||
import { Inner } from "../shared/Inner";
|
||||
import { Label } from "../shared/Label";
|
||||
import { Legend } from "../shared/Legend";
|
||||
import { Messages } from "../shared/Messages";
|
||||
import { Option } from "../shared/Option";
|
||||
import { Options } from "../shared/Options";
|
||||
import { Outer } from "../shared/Outer";
|
||||
import { Wrapper } from "../shared/Wrapper";
|
||||
|
||||
interface RadioInputUniqueProps {
|
||||
options?: OptionsArray | OptionsObjectArray;
|
||||
fieldsetClassName?: string;
|
||||
legendClassName?: string;
|
||||
optionsClassName?: string;
|
||||
optionClassName?: string;
|
||||
}
|
||||
|
||||
type FormbricksProps = RadioInputUniqueProps & UniversalInputProps & NameRequired;
|
||||
@@ -26,10 +34,7 @@ export function Radio(props: FormbricksProps) {
|
||||
const options = useMemo(() => normalizeOptions(props.options), [props.options]);
|
||||
useEffectUpdateSchema(props, inputType);
|
||||
|
||||
const {
|
||||
register,
|
||||
formState: { errors },
|
||||
} = useFormContext();
|
||||
const { register } = useFormContext();
|
||||
const validationRules = getValidationRules(props.validation);
|
||||
|
||||
if (!options || options.length === 0) {
|
||||
@@ -56,12 +61,12 @@ export function Radio(props: FormbricksProps) {
|
||||
|
||||
return (
|
||||
<Outer inputType={inputType} outerClassName={props.outerClassName}>
|
||||
<fieldset className="formbricks-fieldset" name={props.name}>
|
||||
<legend className="formbricks-legend">{props.label}</legend>
|
||||
<Fieldset fieldsetClassName={props.fieldsetClassName} name={props.name}>
|
||||
<Legend legendClassName={props.legendClassName}>{props.label}</Legend>
|
||||
<Help help={props.help} elemId={elemId} />
|
||||
<div className="formbricks-options">
|
||||
<Options optionsClassName={props.optionsClassName}>
|
||||
{options.map((option) => (
|
||||
<div className="formbricks-option">
|
||||
<Option optionClassName={props.optionClassName}>
|
||||
<Wrapper wrapperClassName={props.wrapperClassName}>
|
||||
<Inner innerClassName={props.innerClassName}>
|
||||
<input
|
||||
@@ -75,10 +80,10 @@ export function Radio(props: FormbricksProps) {
|
||||
<Label label={option.label} elemId={`${props.name}-${option.value}`} />
|
||||
</Inner>
|
||||
</Wrapper>
|
||||
</div>
|
||||
</Option>
|
||||
))}
|
||||
</div>
|
||||
</fieldset>
|
||||
</Options>
|
||||
</Fieldset>
|
||||
<Messages {...props} />
|
||||
</Outer>
|
||||
);
|
||||
|
||||
16
packages/react/src/components/shared/Fieldset.tsx
Normal file
16
packages/react/src/components/shared/Fieldset.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
import clsx from "clsx";
|
||||
import React from "react";
|
||||
|
||||
interface FieldsetProps {
|
||||
name: string;
|
||||
fieldsetClassName?: string;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function Fieldset({ name, fieldsetClassName, children }: FieldsetProps) {
|
||||
return (
|
||||
<fieldset className={clsx("formbricks-fieldset", fieldsetClassName)} name={name}>
|
||||
{children}
|
||||
</fieldset>
|
||||
);
|
||||
}
|
||||
11
packages/react/src/components/shared/Legend.tsx
Normal file
11
packages/react/src/components/shared/Legend.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import clsx from "clsx";
|
||||
import React from "react";
|
||||
|
||||
interface LegendProps {
|
||||
legendClassName?: string;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function Legend({ legendClassName, children }: LegendProps) {
|
||||
return <legend className={clsx("formbricks-legend", legendClassName)}>{children}</legend>;
|
||||
}
|
||||
11
packages/react/src/components/shared/Option.tsx
Normal file
11
packages/react/src/components/shared/Option.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import clsx from "clsx";
|
||||
import React from "react";
|
||||
|
||||
interface OptionProps {
|
||||
optionClassName?: string;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function Option({ optionClassName, children }: OptionProps) {
|
||||
return <div className={clsx("formbricks-option", optionClassName)}>{children}</div>;
|
||||
}
|
||||
11
packages/react/src/components/shared/Options.tsx
Normal file
11
packages/react/src/components/shared/Options.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import clsx from "clsx";
|
||||
import React from "react";
|
||||
|
||||
interface OptionsProps {
|
||||
optionsClassName?: string;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function Options({ optionsClassName, children }: OptionsProps) {
|
||||
return <div className={clsx("formbricks-options", optionsClassName)}>{children}</div>;
|
||||
}
|
||||
@@ -1,8 +1,5 @@
|
||||
import clsx from "clsx";
|
||||
import React from "react";
|
||||
import { FieldErrorsImpl, useFormContext } from "react-hook-form";
|
||||
import { Help } from "./Help";
|
||||
import { Messages } from "./Messages";
|
||||
|
||||
interface OuterProps {
|
||||
inputType: string;
|
||||
@@ -11,9 +8,6 @@ interface OuterProps {
|
||||
}
|
||||
|
||||
export function Outer({ inputType, outerClassName, children }: OuterProps) {
|
||||
const {
|
||||
formState: { errors },
|
||||
} = useFormContext();
|
||||
return (
|
||||
<div className={clsx("formbricks-outer", outerClassName)} data-type={inputType}>
|
||||
{children}
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
"lib": ["ES2015", "DOM"],
|
||||
"module": "ESNext",
|
||||
"target": "ES6",
|
||||
"jsx": "react"
|
||||
"jsx": "react",
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user