Skip to content

Commit 5b1dcd5

Browse files
committed
Add atoms PasswordInput component
1 parent 1c5c0f5 commit 5b1dcd5

7 files changed

Lines changed: 134 additions & 0 deletions

File tree

src/assets/scss/4-elements/__elements.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@
1313
@import "anchors";
1414
@import "buttons";
1515
@import "checkboxes";
16+
@import "inputs";
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
input {
2+
@include placeholder() {
3+
color: get-color-neutral("70");
4+
}
5+
@include font-style($font-primary, "base", get-color-neutral("90"), 400);
6+
@include padding(13px, 18px);
7+
8+
border: 1px solid get-color-neutral("30");
9+
border-radius: 5px;
10+
box-sizing: border-box;
11+
12+
&:focus {
13+
@include placeholder() {
14+
color: get-color-neutral("50");
15+
}
16+
}
17+
&:placeholder-shown {
18+
text-overflow: ellipsis;
19+
}
20+
21+
&[type="email"]:disabled,
22+
&[type="password"]:disabled,
23+
&[type="text"]:disabled {
24+
background-color: get-color-neutral("05");
25+
border-color: get-color-neutral("50");
26+
-webkit-text-fill-color: get-color-neutral("90");
27+
opacity: 1; /* required on iOS */
28+
cursor: not-allowed;
29+
}
30+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import React from "react";
2+
import { text, boolean } from "@storybook/addon-knobs";
3+
import { PasswordInput } from "./password-input";
4+
import Faker from "faker";
5+
6+
export default {
7+
component: PasswordInput,
8+
title: "Atoms | Forms / Password Input",
9+
};
10+
11+
export const passwordInputKnobs = () => (
12+
<PasswordInput
13+
disabled={boolean("Disabled", false)}
14+
onChange={() => {}}
15+
id={Faker.random.uuid()}
16+
isVisible={boolean("Is Visible", false)}
17+
placeholder={text("Placeholder", "Please enter password.")}
18+
value={text("Value", "Password")}
19+
isValid={boolean("Is Valid", true)}
20+
/>
21+
);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import React from "react";
2+
3+
describe("PasswordInput", () => {
4+
test.skip("TODO - https://github.com/AndcultureCode/AndcultureCode.JavaScript.React.Components/issues/7", () => {});
5+
});

src/atoms/forms/password-input.tsx

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { InputProperties } from "../interfaces/input-properties";
2+
import { InputTypes } from "../constants/input-types";
3+
import React from "react";
4+
5+
// -----------------------------------------------------------------------------------------
6+
// #region Interfaces
7+
// -----------------------------------------------------------------------------------------
8+
9+
export interface PasswordInputProps extends InputProperties {
10+
id: string;
11+
isVisible: boolean;
12+
13+
/**
14+
* Unique identifier used select the underlying <input> for functional/e2e testing
15+
*/
16+
testId?: string;
17+
}
18+
19+
// #endregion Interfaces
20+
21+
// -----------------------------------------------------------------------------------------
22+
// #region Component
23+
// -----------------------------------------------------------------------------------------
24+
25+
const PasswordInput: React.FC<PasswordInputProps> = (
26+
props: PasswordInputProps
27+
) => {
28+
const {
29+
disabled,
30+
id,
31+
isVisible,
32+
onChange,
33+
placeholder,
34+
testId,
35+
value,
36+
} = props;
37+
38+
const type = isVisible ? InputTypes.Text : InputTypes.Password;
39+
40+
return (
41+
<input
42+
data-test-id={testId}
43+
disabled={disabled}
44+
id={id}
45+
maxLength={20}
46+
onChange={onChange}
47+
placeholder={placeholder}
48+
type={type}
49+
value={value}
50+
/>
51+
);
52+
};
53+
54+
// #endregion Component
55+
56+
// -----------------------------------------------------------------------------------------
57+
// #region Export
58+
// -----------------------------------------------------------------------------------------
59+
60+
export { PasswordInput };
61+
62+
// #endregion Export
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { InputTypes } from "../constants/input-types";
2+
3+
export interface InputProperties {
4+
ariaLabelledBy?: string;
5+
disabled?: boolean;
6+
isValid?: boolean;
7+
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
8+
placeholder?: string;
9+
type?: InputTypes;
10+
value?: string;
11+
}

src/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55
export { Anchor } from "./atoms/anchors/anchor";
66
export { AnchorWithIcon } from "./atoms/anchors/anchor-with-icon";
77
export { Button } from "./atoms/buttons/button";
8+
9+
// Forms
810
export { CheckboxButton } from "./atoms/forms/checkbox-button";
911
export { CheckboxInput } from "./atoms/forms/checkbox-input";
12+
export { PasswordInput } from "./atoms/forms/password-input";
1013

1114
// Icons
1215
export { Icon } from "./atoms/icons/icon";
@@ -33,6 +36,7 @@ export { SvgIcons } from "./atoms/constants/svg-icons";
3336
// -----------------------------------------------------------------------------------------
3437

3538
// To support babel we must use isolatedModules=true, thus we cannot re-export named interfaces
39+
export * from "./atoms/interfaces/input-properties";
3640
export * from "./atoms/interfaces/svg-icon";
3741

3842
// #endregion Interfaces

0 commit comments

Comments
 (0)