From 3e225b95f63648d35dec53a70c442580f1d9291f Mon Sep 17 00:00:00 2001 From: Guoda <121792659+guoda-puidokaite@users.noreply.github.com> Date: Mon, 4 Nov 2024 09:23:15 +0100 Subject: [PATCH] chore(ui): migrate InputGroup to Typescript (#569) * chore(ui): convert inputgroup to ts * chore(ui): remove native select from tests and stories, add deprecated code for .js files * chore(ui): revert Button * chore(ui): fix deprecated tests * chore(ui): remove deprecated component and make suggested changes * chore(ui): make imports more explicit * chore(ui): suggested class name changes --- .changeset/shiny-rivers-fetch.md | 5 + .../InputGroup/InputGroup.component.js | 43 ------ .../InputGroup/InputGroup.component.tsx | 85 ++++++++++++ ...roup.stories.js => InputGroup.stories.tsx} | 62 +-------- .../components/InputGroup/InputGroup.test.js | 102 -------------- .../components/InputGroup/InputGroup.test.tsx | 129 ++++++++++++++++++ .../InputGroup/{index.js => index.ts} | 0 .../components/InputGroup/input-group.scss | 20 +-- packages/ui-components/src/index.js | 2 +- 9 files changed, 236 insertions(+), 212 deletions(-) create mode 100644 .changeset/shiny-rivers-fetch.md delete mode 100644 packages/ui-components/src/components/InputGroup/InputGroup.component.js create mode 100644 packages/ui-components/src/components/InputGroup/InputGroup.component.tsx rename packages/ui-components/src/components/InputGroup/{InputGroup.stories.js => InputGroup.stories.tsx} (54%) delete mode 100644 packages/ui-components/src/components/InputGroup/InputGroup.test.js create mode 100644 packages/ui-components/src/components/InputGroup/InputGroup.test.tsx rename packages/ui-components/src/components/InputGroup/{index.js => index.ts} (100%) diff --git a/.changeset/shiny-rivers-fetch.md b/.changeset/shiny-rivers-fetch.md new file mode 100644 index 000000000..2bb3cc183 --- /dev/null +++ b/.changeset/shiny-rivers-fetch.md @@ -0,0 +1,5 @@ +--- +"@cloudoperators/juno-ui-components": minor +--- + +Migrate the InputGroup component to TypeScript diff --git a/packages/ui-components/src/components/InputGroup/InputGroup.component.js b/packages/ui-components/src/components/InputGroup/InputGroup.component.js deleted file mode 100644 index 4d4dafa65..000000000 --- a/packages/ui-components/src/components/InputGroup/InputGroup.component.js +++ /dev/null @@ -1,43 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Juno contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -import React from "react" -import { Stack } from "../../deprecated_js/Stack/index" -import "./input-group.scss" -import PropTypes from "prop-types" - -/** A component to visually group Buttons, TextInput, and Select elements. */ -export const InputGroup = ({ children = null, className, variant = "default", disabled = false, ...props }) => { - const modifiedChildren = () => { - return React.Children.map(children, (child) => { - const ownVariant = child.props.variant || variant - const ownDisabled = child.props.disabled || disabled - return React.cloneElement(child, { - variant: ownVariant, - disabled: ownDisabled, - }) - }) - } - - return ( - - {modifiedChildren()} - - ) -} - -InputGroup.propTypes = { - /** The children to render */ - children: PropTypes.node, - /** Pass a className to the group */ - className: PropTypes.string, - /** Passing a variant prop to the group will set all child Buttons and Select elements to use that variant, unless specified otherwise on the individual child component */ - variant: PropTypes.oneOf(["default", "primary", "primary-danger", "subdued"]), - /** Disable all elements in the InputGroup */ - disabled: PropTypes.bool, -} diff --git a/packages/ui-components/src/components/InputGroup/InputGroup.component.tsx b/packages/ui-components/src/components/InputGroup/InputGroup.component.tsx new file mode 100644 index 000000000..2107bab50 --- /dev/null +++ b/packages/ui-components/src/components/InputGroup/InputGroup.component.tsx @@ -0,0 +1,85 @@ +/* + * SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Juno contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React, { ReactNode, isValidElement } from "react" +import { Stack } from "../Stack/Stack.component" +import "./input-group.scss" + +type VariantTypes = "default" | "primary" | "primary-danger" | "subdued" + +export interface InputGroupProps { + /** + * The children to render within the InputGroup. + * This can be any React node or a collection of React nodes such as Buttons, TextInput, and Select elements. + */ + children?: React.ReactNode + /** + * Additional CSS class name(s) to apply to the InputGroup for custom styling. + */ + className?: string + /** + * The variant style to apply to the group and its children. + */ + variant?: VariantTypes + /** + * If true, all elements within the InputGroup will be disabled. + * Individual elements can override this setting if needed. + */ + disabled?: boolean +} + +type InheritedProps = { variant?: VariantTypes; disabled?: boolean } + +/** + * Clones a child element with inherited variant and disabled props. + * Individual child props will override inherited ones if specified. + * + * @returns A cloned child element with the variant and disabled props applied. + */ +const cloneElementWithInheritedProps = ( + child: ReactNode, + parentVariant: VariantTypes, + parentDisabled: boolean +): ReactNode => { + if (!isValidElement(child)) return child + + const combinedProps = { + variant: child.props.variant || parentVariant, + disabled: child.props.disabled || parentDisabled, + } + return React.cloneElement(child, combinedProps) +} + +const getClassNames = (baseClassName: string, variant: VariantTypes, disabled: boolean): string => { + return ` + ${baseClassName}-${variant} + ${disabled ? `${baseClassName}-disabled` : ""} + ` +} + +/** + * InputGroup is a component used to visually group related elements such as + * Buttons, TextInput, and Select elements, providing a cohesive styling approach. + */ +export const InputGroup: React.FC = ({ + children = null, + className = "", + variant = "default", + disabled = false, + ...props +}) => { + // Clone each child element with inherited variant and disabled props + const modifiedChildren = React.Children.map(children, (child) => + cloneElementWithInheritedProps(child, variant, disabled) + ) + + const inputGroupClassName = getClassNames("juno-input-group", variant, disabled) + + return ( + + {modifiedChildren} + + ) +} diff --git a/packages/ui-components/src/components/InputGroup/InputGroup.stories.js b/packages/ui-components/src/components/InputGroup/InputGroup.stories.tsx similarity index 54% rename from packages/ui-components/src/components/InputGroup/InputGroup.stories.js rename to packages/ui-components/src/components/InputGroup/InputGroup.stories.tsx index c3cd59b7e..a01955bc6 100644 --- a/packages/ui-components/src/components/InputGroup/InputGroup.stories.js +++ b/packages/ui-components/src/components/InputGroup/InputGroup.stories.tsx @@ -4,11 +4,11 @@ */ import React from "react" -import { InputGroup } from "./index.js" -import { Button } from "../../deprecated_js/Button/index" -import { NativeSelect } from "../NativeSelect/index" -import { NativeSelectOption } from "../NativeSelectOption/index" -import { TextInput } from "../../deprecated_js/TextInput/index" + +import { InputGroup } from "./InputGroup.component" + +import { Button } from "../Button/Button.component" +import { TextInput } from "../TextInput/TextInput.component" export default { title: "WiP/InputGroup", @@ -91,55 +91,3 @@ export const MultipleTextInputsWithButton = { ], }, } - -export const ButtonWithOptions = { - args: { - children: [ -