diff --git a/editor.planx.uk/src/@planx/components/List/Public.tsx b/editor.planx.uk/src/@planx/components/List/Public.tsx deleted file mode 100644 index 11dd56a160..0000000000 --- a/editor.planx.uk/src/@planx/components/List/Public.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { PublicProps } from "@planx/components/ui"; -import { hasFeatureFlag } from "lib/featureFlags"; -import React from "react"; -import { FeaturePlaceholder } from "ui/editor/FeaturePlaceholder"; - -import Card from "../shared/Preview/Card"; -import CardHeader from "../shared/Preview/CardHeader"; -import { List } from "./model"; - -type Props = PublicProps; - -function ListComponent(props: Props) { - if (!hasFeatureFlag("LIST_COMPONENT")) return null; - - return ( - - - - - ); -} - -export default ListComponent; diff --git a/editor.planx.uk/src/@planx/components/List/Public/Fields.tsx b/editor.planx.uk/src/@planx/components/List/Public/Fields.tsx new file mode 100644 index 0000000000..17937ab425 --- /dev/null +++ b/editor.planx.uk/src/@planx/components/List/Public/Fields.tsx @@ -0,0 +1,134 @@ +import Box from "@mui/material/Box"; +import FormControl from "@mui/material/FormControl"; +import FormLabel from "@mui/material/FormLabel"; +import MenuItem from "@mui/material/MenuItem"; +import RadioGroup from "@mui/material/RadioGroup"; +import React from "react"; +import SelectInput from "ui/editor/SelectInput"; +import InputLabel from "ui/public/InputLabel"; +import Input from "ui/shared/Input"; +import InputRowLabel from "ui/shared/InputRowLabel"; + +import { DESCRIPTION_TEXT } from "../../shared/constants"; +import BasicRadio from "../../shared/Radio/BasicRadio"; +import type { NumberField, QuestionField, TextField } from "../model"; + +type Props = T & { id: string }; + +export const TextFieldInput: React.FC> = ({ + id, + data, + required, +}) => ( + + { + if (type === "email") return "email"; + else if (type === "phone") return "tel"; + return "text"; + })(data.type)} + multiline={data.type && ["long", "extraLong"].includes(data.type)} + bordered + id={id} + rows={ + data.type && ["long", "extraLong"].includes(data.type) ? 5 : undefined + } + name="text" + required={required} + inputProps={{ + "aria-describedby": [ + data.description ? DESCRIPTION_TEXT : "", + // TODO: When handling errors, revisit this + // formik.errors.text ? `${ERROR_MESSAGE}-${inputFieldId}` : "", + ] + .filter(Boolean) + .join(" "), + }} + /> + +); + +export const NumberFieldInput: React.FC> = ({ + id, + data, + required, +}) => ( + + + + {data.units && {data.units}} + + +); + +export const RadioFieldInput: React.FC> = ({ + id, + data, +}) => ( + + ({ + color: theme.palette.text.primary, + "&.Mui-focused": { + color: theme.palette.text.primary, + }, + })} + > + {data.title} + + {/* */} + + {data.options.map(({ id, data }) => ( + console.log("change radio")} + /> + ))} + + {/* */} + +); + +export const SelectFieldInput: React.FC> = ({ + id, + data, + required, +}) => ( + + + {data.options.map((option) => ( + + {option.data.text} + + ))} + + +); diff --git a/editor.planx.uk/src/@planx/components/List/Public.test.tsx b/editor.planx.uk/src/@planx/components/List/Public/index.test.tsx similarity index 87% rename from editor.planx.uk/src/@planx/components/List/Public.test.tsx rename to editor.planx.uk/src/@planx/components/List/Public/index.test.tsx index 316d17a08f..a653cbadc5 100644 --- a/editor.planx.uk/src/@planx/components/List/Public.test.tsx +++ b/editor.planx.uk/src/@planx/components/List/Public/index.test.tsx @@ -1,7 +1,7 @@ import React from "react"; import { axe, setup } from "testUtils"; -import ListComponent from "./Editor"; +import ListComponent from "../Editor"; it("should not have any accessibility violations", async () => { const { container } = setup(); diff --git a/editor.planx.uk/src/@planx/components/List/Public/index.tsx b/editor.planx.uk/src/@planx/components/List/Public/index.tsx new file mode 100644 index 0000000000..cb98e7caf9 --- /dev/null +++ b/editor.planx.uk/src/@planx/components/List/Public/index.tsx @@ -0,0 +1,97 @@ +import Box from "@mui/material/Box"; +import Button from "@mui/material/Button"; +import { styled } from "@mui/material/styles"; +import Typography from "@mui/material/Typography"; +import { PublicProps } from "@planx/components/ui"; +import React from "react"; +import InputRow from "ui/shared/InputRow"; + +import Card from "../../shared/Preview/Card"; +import CardHeader from "../../shared/Preview/CardHeader"; +import type { Field, List } from "../model"; +import { + NumberFieldInput, + RadioFieldInput, + SelectFieldInput, + TextFieldInput, +} from "./Fields"; + +type Props = PublicProps; + +const ListCard = styled(Box)(({ theme }) => ({ + padding: theme.spacing(2), + backgroundColor: theme.palette.background.paper, + border: "1px solid darkgray", + display: "flex", + flexDirection: "column", + gap: theme.spacing(2), + marginBottom: theme.spacing(2), +})); + +/** + * Controller to return correct user input for field in schema + */ +const InputField: React.FC = (props) => { + const inputFieldId = `input-${props.type}-${props.index}`; + + switch (props.type) { + case "text": + return ; + case "number": + return ; + case "question": + if (props.data.options.length === 2) { + return ; + } + return ; + } +}; + +function ListComponent({ + info, + policyRef, + howMeasured, + schema, + handleSubmit, + title, + description, +}: Props) { + // TODO: Track user state, allow items to be added and removed + // TODO: Track "active" index + // TODO: Validate min / max + // TODO: Validate user input against schema fields, track errors + // TODO: On submit generate a payload + + return ( + + + + + {schema.type} index + + {schema.fields.map((field, i) => ( + + + + ))} + + + + + + + + ); +} + +export default ListComponent; diff --git a/editor.planx.uk/src/ui/editor/SelectInput.tsx b/editor.planx.uk/src/ui/editor/SelectInput.tsx index 61954a5ae1..926e01b58b 100644 --- a/editor.planx.uk/src/ui/editor/SelectInput.tsx +++ b/editor.planx.uk/src/ui/editor/SelectInput.tsx @@ -9,6 +9,7 @@ export interface Props extends SelectProps { name?: string; children?: ReactNode; onChange?: SelectProps["onChange"]; + bordered?: boolean; } const PREFIX = "SelectInput"; @@ -77,6 +78,7 @@ export default function SelectInput({ value, name, onChange, + bordered, ...props }: Props): FCReturn { return ( @@ -89,7 +91,7 @@ export default function SelectInput({ }} onChange={onChange} IconComponent={ArrowIcon} - input={} + input={} inputProps={{ name, classes: {