From a33485d0c28537176872007adb177c6f271bae95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20D=C3=ADaz=20Gonz=C3=A1lez?= Date: Fri, 25 Nov 2022 10:51:07 +0000 Subject: [PATCH] [web] Add a simple Fieldset component Since PF4/FormFieldGroup[1] looks a bit complex for our use cases right now, we have wrapped the native HTML fieldset/legend elements in a simple Fieldset component which also tweaks a little bit their default look&feel. [1] https://www.patternfly.org/v4/components/form/#formfieldgroup) --- web/src/components/core/Fieldset.jsx | 76 +++++++++++++++++++++++ web/src/components/core/Fieldset.test.jsx | 75 ++++++++++++++++++++++ web/src/components/core/fieldset.scss | 14 +++++ web/src/components/core/index.js | 1 + 4 files changed, 166 insertions(+) create mode 100644 web/src/components/core/Fieldset.jsx create mode 100644 web/src/components/core/Fieldset.test.jsx create mode 100644 web/src/components/core/fieldset.scss diff --git a/web/src/components/core/Fieldset.jsx b/web/src/components/core/Fieldset.jsx new file mode 100644 index 0000000000..2b5c978032 --- /dev/null +++ b/web/src/components/core/Fieldset.jsx @@ -0,0 +1,76 @@ +/* + * Copyright (c) [2022] SUSE LLC + * + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, contact SUSE LLC. + * + * To contact SUSE LLC about this file by physical or electronic mail, you may + * find current contact information at www.suse.com. + */ + +// @ts-check + +import React from "react"; +import { classNames } from "@/utils"; + +import "./fieldset.scss"; + +/** + * + * Convenient component for grouping form fields in "sections" + * by using the native formfield element + * @component + * + * @example Simple usage + *
+ * + * + *
+ * + * @example Using a complex legend and isDisabled prop + *
+ * } + * isDisabled={!encryptionAllowed} + * > + * + * + *
+ * + * @param {object} props + * @param {React.ReactNode} props.legend - The lengend + * @param {boolean} [props.isDisabled=false] - whether the descendant form controls, except any inside legend, are disable + * @param {string} [props.className] - additionally CSS class names + * @param {JSX.Element} [props.children] - the section content + * @param {object} [props.otherProps] fieldset element attributes, see {@link https://html.spec.whatwg.org/#the-fieldset-element} + */ +export default function Fieldset({ + legend, + isDisabled, + className, + children, + ...otherProps +}) { + return ( +
+ {legend && {legend}} + {children} +
+ ); +} diff --git a/web/src/components/core/Fieldset.test.jsx b/web/src/components/core/Fieldset.test.jsx new file mode 100644 index 0000000000..924d8c48cb --- /dev/null +++ b/web/src/components/core/Fieldset.test.jsx @@ -0,0 +1,75 @@ +/* + * Copyright (c) [2022] SUSE LLC + * + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, contact SUSE LLC. + * + * To contact SUSE LLC about this file by physical or electronic mail, you may + * find current contact information at www.suse.com. + */ + +import React from "react"; +import { screen, within } from "@testing-library/react"; +import { installerRender } from "@/test-utils"; +import { Fieldset } from "@components/core"; + +const ComplexLegend = () => { + return ( + <> + + + + ); +}; + +describe("Fieldset", () => { + it("renders a group element", () => { + installerRender(
); + const fieldset = screen.getByRole("group"); + expect(fieldset).toBeInTheDocument(); + }); + + it("renders the given legend", () => { + installerRender(
); + screen.getByRole("group", { name: /Simple legend/i }); + }); + + it("allows using a complex legend", () => { + installerRender(
} />); + const fieldset = screen.getByRole("group", { name: /Using a checkbox.*/i }); + const checkbox = within(fieldset).getByRole("checkbox"); + expect(checkbox).toBeInTheDocument(); + }); + + it("sets children (except legend) as disabled when isDisabled prop is given", () => { + installerRender( +
} isDisabled> + + + + +
+ ); + + const fieldset = screen.getByRole("group", { name: /Using a checkbox/i }); + const legendCheckbox = within(fieldset).getByRole("checkbox", { name: "Using a checkbox in the legend" }); + const inputText = within(fieldset).getByRole("textbox", { name: "Username" }); + const checkbox = within(fieldset).getByRole("checkbox", { name: "Superuser" }); + + expect(fieldset).toHaveAttribute("disabled"); + expect(legendCheckbox).not.toBeDisabled(); + expect(inputText).toBeDisabled(); + expect(checkbox).toBeDisabled(); + }); +}); diff --git a/web/src/components/core/fieldset.scss b/web/src/components/core/fieldset.scss new file mode 100644 index 0000000000..1d955fca67 --- /dev/null +++ b/web/src/components/core/fieldset.scss @@ -0,0 +1,14 @@ +@use "@assets/fonts.scss"; +@use "eos-ds/dist/scss/eos-base/variables/branding.scss"; + +fieldset.d-installer-fieldset { + padding: fonts.$size-base; + border: 0; + border-top: 1px solid branding.$eos-bc-gray-50; + border-image: linear-gradient(45deg, branding.$eos-bc-gray-50, transparent) 1; + + legend { + padding-inline-end: fonts.$size-base; + margin-inline-start: -(fonts.$size-base); + } +} diff --git a/web/src/components/core/index.js b/web/src/components/core/index.js index ca1b5d06b3..10a16f3f7e 100644 --- a/web/src/components/core/index.js +++ b/web/src/components/core/index.js @@ -22,6 +22,7 @@ export { default as About } from "./About"; export { default as Category } from "./Category"; export { default as FormLabel } from "./FormLabel"; +export { default as Fieldset } from "./Fieldset"; export { default as InstallationFinished } from "./InstallationFinished"; export { default as InstallationProgress } from "./InstallationProgress"; export { default as InstallButton } from "./InstallButton";