Skip to content
This repository has been archived by the owner on Jan 23, 2025. It is now read-only.

Commit

Permalink
ui-components: Input
Browse files Browse the repository at this point in the history
Base implementation of Input component
Added Storybook as a playground to validate styles.
Supports only `text` type yet.
  • Loading branch information
koorosh committed May 7, 2020
1 parent ca912ae commit 111f8e6
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 0 deletions.
22 changes: 22 additions & 0 deletions packages/storybook-ui-components/stories/Input.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React, { useState } from "react";
import { withKnobs, text, boolean } from "@storybook/addon-knobs";
import { Input } from "@cockroachlabs/ui-components";

export default {
title: "Input",
components: Input,
decorators: [withKnobs],
};

export const Demo = () => {
const [value, setValue] = useState();
return (
<Input
initialValue={text("Initial value", "Initial text")}
value={text("value", value)}
disabled={boolean("disabled", false)}
onChange={setValue}
invalid={boolean("invalid", false)}
/>
);
};
41 changes: 41 additions & 0 deletions packages/ui-components/src/Input/Input.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
@import "../styles/tokens.scss";

.input {
height: 40px;
border-radius: 3px;
font-family: Source Sans Pro, sans-serif; // TODO (koorosh): replace with token value
font-size: 14px; // TODO (koorosh): replace with token value (default font size)
line-height: 22px;
border: solid 1px $crl-neutral-4;
background-color: $crl-base-white;
padding: 0 crl-gutters(1.5);

&:focus {
border: solid 1px $crl-base-blue;
}

&:hover {
border: solid 1px $crl-neutral-5;
}
}

.invalid {
border: solid 1px $crl-base-red;
background-color: $crl-red-1;
color: $crl-base-red;

&:focus, &:hover {
border: solid 1px $crl-base-red;
}
}

.disabled {
background: $crl-neutral-1;
color: $crl-base-text--light;
border: solid 1px $crl-neutral-3;
cursor: default;

&:focus, &:hover {
border: solid 1px $crl-neutral-3;
}
}
85 changes: 85 additions & 0 deletions packages/ui-components/src/Input/Input.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import React, {
ChangeEvent,
CSSProperties,
useCallback,
useEffect,
useMemo,
useState,
} from "react";
import classNames from "classnames/bind";
import styles from "./input.module.scss";

export interface InputProps {
type?: string;
className?: string;
style?: CSSProperties;
initialValue?: string;
value?: string;
autoComplete?: string;
placeholder?: string;
onChange?: (value: string) => void;
name?: string;
disabled?: boolean;
invalid?: boolean;
}

const cx = classNames.bind(styles);

const Input: React.FC<InputProps> = ({
name,
type = "text",
autoComplete = "off",
className,
style,
value: outerValue,
initialValue = "",
placeholder,
onChange,
disabled = false,
invalid = false,
}) => {
const [value, setValue] = useState(outerValue || initialValue);

useEffect(() => {
setValue(outerValue);
}, [outerValue]);

const onChangeHandler = useCallback(
(event: ChangeEvent<HTMLInputElement>) => {
setValue(event.target.value);
if (onChange) {
onChange(event.target.value);
}
},
[onChange],
);

const classnames = useMemo(
() =>
cx(
"input",
{
disabled,
invalid,
},
className,
),
[className, invalid, disabled],
);

return (
<input
name={name}
type={type}
value={value}
placeholder={placeholder}
className={classnames}
style={style}
onChange={onChangeHandler}
autoComplete={autoComplete}
disabled={disabled}
/>
);
};

export default Input;
1 change: 1 addition & 0 deletions packages/ui-components/src/Input/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as Input } from "./Input";
1 change: 1 addition & 0 deletions packages/ui-components/src/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { Badge } from "./Badge";
export { Input } from "./Input";

0 comments on commit 111f8e6

Please sign in to comment.