diff --git a/packages/orbit-components/src/deprecated/InputGroup/DeprecatedInputGroup.stories.tsx b/packages/orbit-components/src/deprecated/InputGroup/DeprecatedInputGroup.stories.tsx deleted file mode 100644 index 34e21865ca..0000000000 --- a/packages/orbit-components/src/deprecated/InputGroup/DeprecatedInputGroup.stories.tsx +++ /dev/null @@ -1,286 +0,0 @@ -import * as React from "react"; -import { action } from "@storybook/addon-actions"; -import { text, array, select } from "@storybook/addon-knobs"; - -import InputField from "../InputField"; -import Select from "../Select"; -import { SIZE_OPTIONS } from "./consts"; -import CountryFlag from "../../CountryFlag"; -import RenderInRtl from "../../utils/rtl/RenderInRtl"; -import SPACINGS_AFTER from "../../common/getSpacingToken/consts"; - -import InputGroup from "."; - -export default { - title: "Deprecated InputGroup", -}; - -export const DateOfBirth = () => { - const label = text("Label", "Date of birth"); - const flex = array("Flex", [" 60px", "1 1 100%", " 0 90px"]); - const error = text("Error", ""); - const help = text("Help", ""); - - const selectOptions = [ - { value: "January", label: "January" }, - { value: "February", label: "February" }, - { value: "March", label: "March" }, - { value: "April", label: "April" }, - { value: "May", label: "May" }, - { value: "June", label: "June" }, - { value: "July", label: "July" }, - { value: "August", label: "August" }, - { value: "September", label: "September" }, - { value: "October", label: "October" }, - { value: "November", label: "November" }, - { value: "December", label: "December" }, - ]; - const selectValue = select( - "Select Value", - selectOptions.map(opt => opt.value), - selectOptions[0].value, - ); - - return ( - - - } - /> - - - ); -}; - -PhoneNumber.story = { - name: "Phone number", - - parameters: { - info: "Some description about this type of InputGroup in general.", - }, -}; - -export const OnChangeBehaviour = () => { - const inputValue = text("Input Value", ""); - - return ( -
- - - - - - - - - -
- ); -}; - -OnChangeBehaviour.story = { - name: "onChange behaviour", - - parameters: { - info: "Some description about this type of InputGroup in general.", - }, -}; - -export const WithHelp = () => { - const label = text("Label", "Label"); - const help = text("Help", "Help message"); - const inputValue = text("Input Value", ""); - - return ( - - - - - ); -}; - -WithHelp.story = { - name: "With help", - - parameters: { - info: "You can try all possible configurations of this component. However, check Orbit.Kiwi for more detailed design guidelines.", - }, -}; - -export const WithError = () => { - const label = text("Label", "Label"); - const error = text("Error", "Error message (explain how to solve it)"); - const inputValue = text("Input Value", ""); - - return ( - - - - - ); -}; - -WithError.story = { - name: "With error", - - parameters: { - info: "You can try all possible configurations of this component. However, check Orbit.Kiwi for more detailed design guidelines.", - }, -}; - -export const Playground = () => { - const label = text("Label", "Phone number"); - const flex = array("Flex", ["1 0 200px", "1 1 100%", "1 0 150px", "0 1 50%"]); - const size = select("Size", Object.values(SIZE_OPTIONS), SIZE_OPTIONS.NORMAL); - const error = text("Error", ""); - const help = text("Help", ""); - - const selectOptions = [ - { value: 1, label: "First item" }, - { value: 2, label: "Second item" }, - ]; - const selectValue = select( - "Select Value", - selectOptions.map(opt => opt.value), - selectOptions[0].value, - ); - const placeholder = text("Input Placeholder", "Placeholder"); - const inputValue = text("Input Value", ""); - const dataTest = text("dataTest", "test"); - const spaceAfter = select("spaceAfter", Object.values(SPACINGS_AFTER), SPACINGS_AFTER.NORMAL); - - return ( - - - - - ); -}; - -Playground.story = { - parameters: { - info: "Some description about this type of InputGroup in general.", - }, -}; - -export const Rtl = () => { - const flex = array("Flex", ["0 0 60px", "1 1 100%", "0 0 90px"]); - const selectOptions = [ - { value: "January", label: "January" }, - { value: "February", label: "February" }, - { value: "March", label: "March" }, - { value: "April", label: "April" }, - { value: "May", label: "May" }, - { value: "June", label: "June" }, - { value: "July", label: "July" }, - { value: "August", label: "August" }, - { value: "September", label: "September" }, - { value: "October", label: "October" }, - { value: "November", label: "November" }, - { value: "December", label: "December" }, - ]; - const selectValue = select( - "Select Value", - selectOptions.map(opt => opt.value), - selectOptions[0].value, - ); - return ( - - - - - -``` - -## Props - -Table below contains all types of the props available in InputGroup component. - -| Name | Type | Default | Description | -| :----------- | :-------------------------- | :----------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **children** | `React.Node` | | The content of the InputGroup, normally **InputField** or **Select**. | -| dataTest | `string` | | Optional prop for testing purposes. | -| error | `React.Node` | | The error to display beneath the InputGroup. [See Functional specs](#functional-specs) | -| flex | `string` or `Array` | `"0 1 auto"` | The flex attribute(s) for children of the InputGroup. [See Functional specs](#functional-specs) | -| help | `React.Node` | | The help to display beneath the InputGroup. | -| label | `Translation` | | The label for the InputGroup. [See Functional specs](#functional-specs) | -| onChange | `event => void \| Promise` | | Function for handling onClick event. [See Functional specs](#functional-specs) | -| onFocus | `event => void \| Promise` | | Function for handling onFocus event. [See Functional specs](#functional-specs) | -| onBlur | `event => void \| Promise` | | Function for handling onBlur event. [See Functional specs](#functional-specs) | -| size | [`enum`](#enum) | `"normal"` | The size of the InputField. [See Functional specs](#functional-specs) | -| spaceAfter | `enum` | | Additional `margin-bottom` after component. [See this docs](https://github.com/kiwicom/orbit/tree/master/packages/orbit-components/src/common/getSpacingToken) | - -### enum - -| size | -| :--------- | -| `"small"` | -| `"normal"` | - -## Functional specs - -- The `error` prop overwrites the `help` prop, due to higher priority. - -- Define `error` or `help` only for the **InputGroup**. Any `error` or `help` in InputField or Select won't be displayed. - -- You can set up different `flex` attribute for every children, or use one for all. See [flex property docs](https://www.w3schools.com/cssref/css3_pr_flex.asp) for more information. - -- The color of the label will turn into cloud shade when all children have some filled value. - -- If the passed children into the InputGroup won't have any callbacks - either `onChange`, `onFocus` or `onBlur`, the passed callback of the InputGroup will be used. - -- Define `size` only for the **InputGroup**, it will set up the proper styling for everything automatically. diff --git a/packages/orbit-components/src/deprecated/InputGroup/__tests__/index.test.tsx b/packages/orbit-components/src/deprecated/InputGroup/__tests__/index.test.tsx deleted file mode 100644 index 81401ebb53..0000000000 --- a/packages/orbit-components/src/deprecated/InputGroup/__tests__/index.test.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import * as React from "react"; -import { render, screen, fireEvent } from "@testing-library/react"; -import userEvent from "@testing-library/user-event"; - -import InputGroup from ".."; -import InputField from "../../../InputField"; -import defaultTheme from "../../../defaultTheme"; - -describe("InputGroup", () => { - it("should render label", () => { - render( - - - , - ); - expect(screen.getByRole("group", { name: "Label" })).toBeInTheDocument(); - }); - it("should pass dataTest to data-test", () => { - render( - - - , - ); - expect(screen.getByTestId("test")).toBeInTheDocument(); - }); - it("should add margin using spaceAfter", () => { - render( - - - , - ); - expect(screen.getByRole("group")).toHaveStyle({ marginBottom: defaultTheme.orbit.spaceSmall }); - }); - it("should render help message", () => { - render( - - - , - ); - expect(screen.getByText("help message")).toBeInTheDocument(); - }); - it("should render error message", () => { - render( - - - , - ); - expect(screen.getByText("error message")).toBeInTheDocument(); - }); - it("should remove labels, help and error messages from child inputs", () => { - render( - - - - , - ); - expect(screen.queryByLabelText("Label")).not.toBeInTheDocument(); - expect(screen.queryByText("help message")).not.toBeInTheDocument(); - expect(screen.queryByText("error message")).not.toBeInTheDocument(); - }); - it("should pass event handlers to child inputs", () => { - const onChange = jest.fn(); - const onFocus = jest.fn(); - const onBlur = jest.fn(); - render( - - - , - ); - const input = screen.getByRole("textbox"); - userEvent.type(input, "text"); - expect(onChange).toHaveBeenCalled(); - expect(onFocus).toHaveBeenCalled(); - fireEvent.blur(input); - expect(onBlur).toHaveBeenCalled(); - }); -}); diff --git a/packages/orbit-components/src/deprecated/InputGroup/consts.ts b/packages/orbit-components/src/deprecated/InputGroup/consts.ts deleted file mode 100644 index 599dbe6e1b..0000000000 --- a/packages/orbit-components/src/deprecated/InputGroup/consts.ts +++ /dev/null @@ -1,9 +0,0 @@ -export enum SIZE_OPTIONS { - SMALL = "small", - NORMAL = "normal", -} - -export enum TOKENS { - height = "height", - heightLine = "heightLine", -} diff --git a/packages/orbit-components/src/deprecated/InputGroup/index.js.flow b/packages/orbit-components/src/deprecated/InputGroup/index.js.flow deleted file mode 100644 index 8d4943fa7a..0000000000 --- a/packages/orbit-components/src/deprecated/InputGroup/index.js.flow +++ /dev/null @@ -1,30 +0,0 @@ -// @flow -/* - DOCUMENTATION: https://orbit.kiwi/components/inputgroup/ -*/ -import * as React from "react"; - -import type { Globals, Translation } from "../../common/common.js.flow"; -import type { spaceAfter } from "../../common/getSpacingToken/index.js.flow"; - -export type Props = {| - ...Globals, - ...spaceAfter, - +label?: Translation, - +flex?: string | Array, - +size?: "small" | "normal", - +help?: React.Node, - +children: React.Node, - +error?: React.Node, - +onChange?: ( - ev: SyntheticInputEvent | SyntheticInputEvent, - ) => void | Promise, - +onFocus?: ( - ev: SyntheticInputEvent | SyntheticInputEvent, - ) => void | Promise, - +onBlur?: ( - ev: SyntheticInputEvent | SyntheticInputEvent, - ) => void | Promise, -|}; - -declare export default React.ComponentType; diff --git a/packages/orbit-components/src/deprecated/InputGroup/index.tsx b/packages/orbit-components/src/deprecated/InputGroup/index.tsx deleted file mode 100644 index c182a34bde..0000000000 --- a/packages/orbit-components/src/deprecated/InputGroup/index.tsx +++ /dev/null @@ -1,275 +0,0 @@ -import * as React from "react"; -import styled, { css } from "styled-components"; - -import defaultTheme from "../../defaultTheme"; -import FormLabel from "../../FormLabel"; -import { FakeInput, Input, InputContainer } from "../InputField"; -import { SelectContainer } from "../Select"; -import FormFeedback from "../FormFeedback"; -import { SIZE_OPTIONS, TOKENS } from "./consts"; -import { right, rtlSpacing } from "../../utils/rtl"; -import getSpacingToken from "../../common/getSpacingToken"; -import { useRandomIdSeed } from "../../hooks/useRandomId"; -import formElementFocus from "../InputField/helpers/formElementFocus"; -import mq from "../../utils/mediaQuery"; -import type { Props } from "./types"; - -const getToken = - name => - ({ theme, size }) => { - const tokens = { - [TOKENS.height]: { - [SIZE_OPTIONS.SMALL]: theme.orbit.heightInputSmall, - [SIZE_OPTIONS.NORMAL]: theme.orbit.heightInputNormal, - }, - [TOKENS.heightLine]: { - [SIZE_OPTIONS.SMALL]: "16px", - [SIZE_OPTIONS.NORMAL]: "24px", - }, - }; - - return tokens[name][size]; - }; - -const FakeGroup = styled(({ children, className }) => ( - {children} -))` - ${({ theme, error, disabled, active }) => css` - width: 100%; - display: block; - position: absolute; - top: 0px; - left: 0; - z-index: 1; - box-sizing: border-box; - height: ${getToken(TOKENS.height)}; - box-shadow: ${`inset 0 0 0 ${theme.orbit.borderWidthInput} ${theme.orbit.borderColorInput}`}; // Normal state - box-shadow: ${error && - `inset 0 0 0 ${theme.orbit.borderWidthInput} ${theme.orbit.borderColorInputError}`}; // Error state - ${active && formElementFocus}; // Active state - background-color: ${disabled - ? theme.orbit.backgroundInputDisabled - : theme.orbit.backgroundInput}; - font-size: ${theme.orbit.fontSizeInputNormal}; - transition: box-shadow ${theme.orbit.durationFast} ease-in-out; - - border-radius: 6px; - ${mq.tablet(css` - border-radius: ${theme.orbit.borderRadiusNormal}; - `)}; - - &:hover { - box-shadow: inset 0 0 0 - ${`${theme.orbit.borderWidthInput} ${ - error ? theme.orbit.borderColorInputErrorHover : theme.orbit.borderColorInputHover - }`}; - } - `} -`; - -FakeGroup.defaultProps = { - theme: defaultTheme, -}; - -const StyledChildren = styled.div` - display: flex; - position: relative; -`; - -const StyledChild = styled.div<{ flex?: Props["flex"] }>` - flex: ${({ flex }) => flex}; - padding: ${({ theme }) => rtlSpacing(`0 ${theme.orbit.spaceXSmall} 0 0`)}; - :last-child { - padding: 0; - } -`; - -StyledChild.defaultProps = { - theme: defaultTheme, -}; - -const StyledInputGroup = styled( - ({ children, className, dataTest, role, ariaLabelledby, forwardRef, dataState }) => ( -
- {children} -
- ), -)` - display: flex; - width: 100%; - flex-direction: column; - position: relative; - margin-bottom: ${getSpacingToken}; - - ${StyledChild} { - ${FakeInput} { - box-shadow: none; - background-color: transparent; - display: none; - align-items: center; - justify-content: flex-end; - } - - ${SelectContainer} { - background-color: transparent; - > select { - box-shadow: none; - background-color: transparent; - &:focus { - box-shadow: none; - } - } - } - - ${InputContainer}:after, ${SelectContainer}:after { - content: " "; - position: absolute; - top: 50%; - transform: translateY(-50%); - ${right}: 0; - height: ${getToken(TOKENS.heightLine)}; - width: 1px; - background-color: ${({ theme, error, active }) => - error && !active ? theme.orbit.borderColorInputError : theme.orbit.borderColorInput}; - transition: background-color ${({ theme }) => theme.orbit.durationFast} ease-in-out; - display: block; - z-index: 2; - } - - &:last-of-type { - ${InputContainer}:after, ${SelectContainer}:after { - content: none; - } - } - } - - ${StyledChild} ${FormLabel} { - display: ${({ label }) => label && "none"}; - } - - ${Input}:focus ~ ${FakeInput} { - box-shadow: none; - } -`; - -StyledInputGroup.defaultProps = { - theme: defaultTheme, -}; - -const findPropInChild = (propToFind, children) => { - return React.Children.toArray(children) - .map(el => { - // @ts-expect-error ts-migrate will be removed after deprecation - if (el.props && typeof el.props[propToFind] !== "undefined") return el.props[propToFind]; - return null; - }) - .filter(el => el !== null && el !== ""); -}; - -const InputGroup = ({ - children, - label, - flex = "0 1 auto", - size = SIZE_OPTIONS.NORMAL, - help, - error, - dataTest, - spaceAfter = "medium", - onFocus, - onBlur, - onChange, -}: Props) => { - const [active, setActive] = React.useState(false); - const [filled, setFilled] = React.useState(false); - const randomId = useRandomIdSeed(); - const inputID = randomId("inputGroupID"); - - const isFilled = React.useCallback( - () => - setFilled( - findPropInChild("value", children).length === React.Children.toArray(children).length, - ), - [children], - ); - - React.useEffect(() => { - isFilled(); - }, [isFilled]); - - const handleFocus = (ev: React.SyntheticEvent) => { - setActive(true); - if (onFocus) { - onFocus(ev); - } - }; - - const handleBlur = (ev: React.SyntheticEvent) => { - isFilled(); - setActive(false); - if (onBlur) { - onBlur(ev); - } - }; - - const handleChange = (ev: React.SyntheticEvent) => { - isFilled(); - - if (onChange) { - onChange(ev); - } - }; - - return ( - - {label && ( - - {label} - - )} - - {React.Children.map(children, (item, key) => { - // either array, array with one length or string - // if it's not defined, use the first or string - const childFlex = Array.isArray(flex) && flex.length !== 1 ? flex[key] || flex[0] : flex; - return ( - - {/* @ts-expect-error suppressed until removed */} - {React.cloneElement(item, { - size, - label: undefined, - help: undefined, - error: undefined, - /* @ts-expect-error suppressed until removed */ - onChange: item.props.onChange != null ? item.props.onChange : handleChange, - /* @ts-expect-error suppressed until removed */ - onBlur: item.props.onBlur != null ? item.props.onChange : handleBlur, - /* @ts-expect-error suppressed until removed */ - onFocus: item.props.onFocus != null ? item.props.onFocus : handleFocus, - })} - - ); - })} - - - - - ); -}; - -export default InputGroup; diff --git a/packages/orbit-components/src/deprecated/InputGroup/types.d.ts b/packages/orbit-components/src/deprecated/InputGroup/types.d.ts deleted file mode 100644 index 134f4626e7..0000000000 --- a/packages/orbit-components/src/deprecated/InputGroup/types.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -// Type definitions for @kiwicom/orbit-components -// Project: http://github.com/kiwicom/orbit - -import type * as React from "react"; - -import type * as Common from "../../common/types"; - -type Size = "small" | "normal"; -type Event = Common.Event>; - -export interface Props extends Common.Globals, Common.SpaceAfter { - readonly label?: Common.Translation; - readonly flex?: string | string[]; - readonly size?: Size; - readonly help?: React.ReactNode; - readonly children: React.ReactNode; - readonly error?: React.ReactNode; - readonly onChange?: Event; - readonly onFocus?: Event; - readonly onBlur?: Event; -}