From 4a212b729c5d36de556397c28a14dd1018b4f23e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20Ja=C5=9Bkiewicz?= Date: Mon, 2 Sep 2024 23:04:47 +0200 Subject: [PATCH] chore(ui): introduce TS version of TextBox and dependencies (#289) * chore(ui): Add TS version of TextArea, Label and FormHint * fix(ui): fix FormHint TS types * fix(ui): playbook naming fix * fix(ui): playbook stories fix * fix(ui): fix textarea story * fix(ui): format and naming fix --------- Co-authored-by: gjaskiewicz@objectivity.co.uk --- .../CheckboxGroup/CheckboxGroup.component.js | 2 +- .../components/FormHint/FormHint.component.js | 2 + .../components/FormHint/FormHint.stories.js | 2 +- .../FormHintTs/FormHint.component.tsx | 54 ++++ .../FormHintTs/FormHint.stories.tsx | 77 +++++ .../components/FormHintTs/FormHint.test.tsx | 72 +++++ .../src/components/FormHintTs/index.ts | 6 + .../src/components/Label/Label.component.js | 2 +- .../src/components/Label/Label.stories.js | 4 +- .../components/LabelTs/Label.component.tsx | 109 +++++++ .../src/components/LabelTs/Label.stories.ts | 32 ++ .../src/components/LabelTs/Label.test.tsx | 55 ++++ .../src/components/LabelTs/index.ts | 6 + .../SecretText/SecretText.component.js | 2 +- .../TextAreaTs/Textarea.component.tsx | 290 ++++++++++++++++++ .../TextAreaTs/Textarea.stories.tsx | 98 ++++++ .../components/TextAreaTs/Textarea.test.tsx | 152 +++++++++ .../src/components/TextAreaTs/index.ts | 6 + .../components/Textarea/Textarea.stories.js | 2 +- 19 files changed, 966 insertions(+), 7 deletions(-) create mode 100644 packages/ui-components/src/components/FormHintTs/FormHint.component.tsx create mode 100644 packages/ui-components/src/components/FormHintTs/FormHint.stories.tsx create mode 100644 packages/ui-components/src/components/FormHintTs/FormHint.test.tsx create mode 100644 packages/ui-components/src/components/FormHintTs/index.ts create mode 100644 packages/ui-components/src/components/LabelTs/Label.component.tsx create mode 100644 packages/ui-components/src/components/LabelTs/Label.stories.ts create mode 100644 packages/ui-components/src/components/LabelTs/Label.test.tsx create mode 100644 packages/ui-components/src/components/LabelTs/index.ts create mode 100644 packages/ui-components/src/components/TextAreaTs/Textarea.component.tsx create mode 100644 packages/ui-components/src/components/TextAreaTs/Textarea.stories.tsx create mode 100644 packages/ui-components/src/components/TextAreaTs/Textarea.test.tsx create mode 100644 packages/ui-components/src/components/TextAreaTs/index.ts diff --git a/packages/ui-components/src/components/CheckboxGroup/CheckboxGroup.component.js b/packages/ui-components/src/components/CheckboxGroup/CheckboxGroup.component.js index 6a6b616f7..248f837d4 100644 --- a/packages/ui-components/src/components/CheckboxGroup/CheckboxGroup.component.js +++ b/packages/ui-components/src/components/CheckboxGroup/CheckboxGroup.component.js @@ -5,7 +5,7 @@ import React, { useState, useEffect, useMemo, createContext, useId } from "react" import PropTypes from "prop-types" -import { Label } from "../Label/index.js" +import { Label } from "../Label/index" import { Icon } from "../Icon/index" import { FormHint } from "../FormHint/index" diff --git a/packages/ui-components/src/components/FormHint/FormHint.component.js b/packages/ui-components/src/components/FormHint/FormHint.component.js index 5e9121668..da63f92c2 100644 --- a/packages/ui-components/src/components/FormHint/FormHint.component.js +++ b/packages/ui-components/src/components/FormHint/FormHint.component.js @@ -39,6 +39,8 @@ export const FormHint = ({ children = null, text = "", variant = "help", classNa ) } +FormHint.displayName = "FormHint Js" + FormHint.propTypes = { /** The children to render as a hint associated with a form element */ children: PropTypes.node, diff --git a/packages/ui-components/src/components/FormHint/FormHint.stories.js b/packages/ui-components/src/components/FormHint/FormHint.stories.js index a4ae7bc67..0bfb5191c 100644 --- a/packages/ui-components/src/components/FormHint/FormHint.stories.js +++ b/packages/ui-components/src/components/FormHint/FormHint.stories.js @@ -8,7 +8,7 @@ import PropTypes from "prop-types" import { FormHint } from "./index.js" export default { - title: "Forms/FormHint", + title: "Forms/FormHint (JS, deprecated)", component: FormHint, argTypes: { children: { diff --git a/packages/ui-components/src/components/FormHintTs/FormHint.component.tsx b/packages/ui-components/src/components/FormHintTs/FormHint.component.tsx new file mode 100644 index 000000000..9372bf0ea --- /dev/null +++ b/packages/ui-components/src/components/FormHintTs/FormHint.component.tsx @@ -0,0 +1,54 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Juno contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React, { ReactNode } from "react" + +const baseStyles = ` + jn-text-xs + jn-mt-1 +` + +type FormHintVariant = "help" | "error" | "success" + +const variantStyles = (variant: FormHintVariant) => { + switch (variant) { + case "success": + return "jn-text-theme-success" + case "error": + return "jn-text-theme-error" + default: + return "jn-text-theme-light" + } +} + +export const FormHint = ({ children = null, text = "", variant = "help", className, ...props }: FormHintProps) => { + return ( +
+ {children || text} +
+ ) +} + +FormHint.displayName = "FormHint" + +export interface FormHintProps { + /** The children to render as a hint associated with a form element */ + children?: ReactNode + /** The text to render. If both children and text are passed, children will rendered */ + text?: ReactNode | string + /** The variant of the the hint. Defaults to 'help'. */ + variant?: FormHintVariant + /** Pass a custom className */ + className?: string +} diff --git a/packages/ui-components/src/components/FormHintTs/FormHint.stories.tsx b/packages/ui-components/src/components/FormHintTs/FormHint.stories.tsx new file mode 100644 index 000000000..80f8d398f --- /dev/null +++ b/packages/ui-components/src/components/FormHintTs/FormHint.stories.tsx @@ -0,0 +1,77 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Juno contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from "react" +import PropTypes from "prop-types" +import { FormHint } from "./index" + +export default { + title: "Forms/FormHint", + component: FormHint, + argTypes: { + children: { + control: false, + }, + }, +} + +type TemplateProps = { + children: React.ReactNode +} + +const Template = ({ children, ...args }: TemplateProps) => {children} +Template.propTypes = { + children: PropTypes.node, +} + +export const Default = { + render: Template, + + args: { + text: "A simple hint to be associated with a form input", + }, +} + +export const WithChildren = { + render: Template, + + args: { + children: ( + <> + A FormHint with a Link. + + ), + }, +} + +export const WithTextAsChildren = { + render: Template, + + args: { + text: ( + <> + A FormHint with a Link. + + ), + }, +} + +export const ErrorVariant = { + render: Template, + + args: { + variant: "error", + text: "A FormHint containing an error or invalidation message", + }, +} + +export const SuccessVariant = { + render: Template, + + args: { + variant: "success", + text: "A FormHint containg a success or validation message", + }, +} diff --git a/packages/ui-components/src/components/FormHintTs/FormHint.test.tsx b/packages/ui-components/src/components/FormHintTs/FormHint.test.tsx new file mode 100644 index 000000000..2f599c2bd --- /dev/null +++ b/packages/ui-components/src/components/FormHintTs/FormHint.test.tsx @@ -0,0 +1,72 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Juno contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as React from "react" +import { render, screen } from "@testing-library/react" +import { FormHint } from "./index" + +describe("FormHint", () => { + test("renders a FormHint", () => { + render() + expect(screen.getByTestId("my-form-hint")).toBeInTheDocument() + }) + + test("renders children as passed", () => { + render( + + + + ) + expect(screen.getByTestId("my-form-hint")).toBeInTheDocument() + expect(screen.getByRole("button")).toBeInTheDocument() + }) + + test("renders a text as passed", () => { + render() + expect(screen.getByTestId("my-form-hint")).toBeInTheDocument() + expect(screen.getByTestId("my-form-hint")).toHaveTextContent("My form-related message") + }) + + test("renders children if both children and text have been passed", () => { + render( + + <>abc + + ) + expect(screen.getByTestId("my-form-hint")).toBeInTheDocument() + expect(screen.getByTestId("my-form-hint")).toHaveTextContent("abc") + expect(screen.getByTestId("my-form-hint")).not.toHaveTextContent("123") + }) + + test("renders a help message by default", () => { + render() + expect(screen.getByTestId("my-form-hint")).toBeInTheDocument() + expect(screen.getByTestId("my-form-hint")).toHaveClass("juno-form-hint-help") + }) + + test("renders an error message as passed", () => { + render() + expect(screen.getByTestId("my-form-hint")).toBeInTheDocument() + expect(screen.getByTestId("my-form-hint")).toHaveClass("juno-form-hint-error") + }) + + test("renders a success message as passed", () => { + render() + expect(screen.getByTestId("my-form-hint")).toBeInTheDocument() + expect(screen.getByTestId("my-form-hint")).toHaveClass("juno-form-hint-success") + }) + + test("renders a custom className", () => { + render() + expect(screen.getByTestId("my-form-hint")).toBeInTheDocument() + expect(screen.getByTestId("my-form-hint")).toHaveClass("my-custom-class") + }) + + test("renders all props as passed", () => { + render() + expect(screen.getByTestId("23")).toBeInTheDocument() + expect(screen.getByTestId("23")).toHaveAttribute("data-lolol") + }) +}) diff --git a/packages/ui-components/src/components/FormHintTs/index.ts b/packages/ui-components/src/components/FormHintTs/index.ts new file mode 100644 index 000000000..1359457dc --- /dev/null +++ b/packages/ui-components/src/components/FormHintTs/index.ts @@ -0,0 +1,6 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Juno contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +export { FormHint } from "./FormHint.component" diff --git a/packages/ui-components/src/components/Label/Label.component.js b/packages/ui-components/src/components/Label/Label.component.js index b56ba65b7..4c155b98c 100644 --- a/packages/ui-components/src/components/Label/Label.component.js +++ b/packages/ui-components/src/components/Label/Label.component.js @@ -90,7 +90,7 @@ export const Label = React.forwardRef( } ) -Label.displayName = "Label" +Label.displayName = "Label (JS)" Label.propTypes = { /** Pass a string of text to be rendered as contents. Required. */ diff --git a/packages/ui-components/src/components/Label/Label.stories.js b/packages/ui-components/src/components/Label/Label.stories.js index ee962be90..296ad0720 100644 --- a/packages/ui-components/src/components/Label/Label.stories.js +++ b/packages/ui-components/src/components/Label/Label.stories.js @@ -3,10 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { Label } from "./index.js" +import { Label } from "./index" export default { - title: "Forms/Label", + title: "Forms/Label (JS, deprecated)", component: Label, argTypes: {}, } diff --git a/packages/ui-components/src/components/LabelTs/Label.component.tsx b/packages/ui-components/src/components/LabelTs/Label.component.tsx new file mode 100644 index 000000000..9768b31d9 --- /dev/null +++ b/packages/ui-components/src/components/LabelTs/Label.component.tsx @@ -0,0 +1,109 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Juno contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from "react" + +const labelstyles = ` + jn-text-theme-high + jn-text-base + jn-transform + jn-origin-top-left + jn-transition-all + jn-duration-100 + jn-ease-in-out + jn-z-10 +` + +const floatingStyles = ` + jn-absolute +` + +const minimizedStyles = ` + jn-scale-75 + -jn-translate-y-[0.4375rem] +` + +const requiredstyles = ` + jn-inline-block + jn-w-1 + jn-h-1 + jn-rounded-full + jn-align-top + jn-ml-1 + jn-mt-2 + jn-bg-theme-required +` + +const disabledstyles = ` + jn-opacity-50 + jn-cursor-not-allowed +` + +/** + * A re-usable Label component + */ + +export const Label = React.forwardRef( + ( + { + text = "", + htmlFor = undefined, + required = false, + className = "", + disabled = false, + floating = false, + minimized = false, + ...props + }, + forwardedRef + ) => { + return ( + + ) + } +) + +Label.displayName = "Label" + +export interface LabelProps { + /** Pass a string of text to be rendered as contents. Required. */ + text?: string + /** An Id of an input element to associate the label with */ + htmlFor?: string + /** Required */ + required?: boolean + /** Pass a className */ + className?: string + /** Label for a disabled input */ + disabled?: boolean + /** Whether the label is floating */ + floating?: boolean + /** Whether the label is minimized. Requires `floating` set to TRUE, otherwise it will have no effect. */ + minimized?: boolean +} diff --git a/packages/ui-components/src/components/LabelTs/Label.stories.ts b/packages/ui-components/src/components/LabelTs/Label.stories.ts new file mode 100644 index 000000000..d3ad6ed8c --- /dev/null +++ b/packages/ui-components/src/components/LabelTs/Label.stories.ts @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Juno contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { Label } from "./index" + +export default { + title: "Forms/Label", + component: Label, + argTypes: {}, +} + +export const Default = { + args: { + text: "My Label", + }, +} + +export const Disabled = { + args: { + text: "My disabled label", + disabled: true, + }, +} + +export const Required = { + args: { + text: "My required label", + required: true, + }, +} diff --git a/packages/ui-components/src/components/LabelTs/Label.test.tsx b/packages/ui-components/src/components/LabelTs/Label.test.tsx new file mode 100644 index 000000000..0de041c95 --- /dev/null +++ b/packages/ui-components/src/components/LabelTs/Label.test.tsx @@ -0,0 +1,55 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Juno contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import * as React from "react" +import { render, screen } from "@testing-library/react" +import { Label } from "./index" + +describe("Label", () => { + test("renders a label with a text as passed", () => { + render(