Skip to content

Commit fd15e87

Browse files
Gannu456Brayan-724
andauthored
feat(react): add Input component (#52)
Co-authored-by: Apika Luca <[email protected]>
1 parent c0944f0 commit fd15e87

File tree

8 files changed

+115
-3
lines changed

8 files changed

+115
-3
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from "./input";
2+
export * from "./input.types";
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import clsx from "clsx";
2+
import { InputFieldProps } from "./input.types";
3+
4+
export function Input({
5+
errorMessage,
6+
hasError = !!errorMessage,
7+
icon,
8+
disabled,
9+
className,
10+
...props
11+
}: InputFieldProps) {
12+
return (
13+
<div className="rustlanges-input__container">
14+
<div
15+
className={clsx(
16+
"rustlanges-input",
17+
hasError && "rustlanges-input--error",
18+
className
19+
)}
20+
>
21+
{icon && <span className="rustlanges-input__icon">{icon}</span>}
22+
<input
23+
disabled={disabled}
24+
className="rustlanges-input__inner"
25+
{...props}
26+
/>
27+
</div>
28+
{hasError && errorMessage && (
29+
<span className="rustlanges-input__error">{errorMessage}</span>
30+
)}
31+
</div>
32+
);
33+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { InputHTMLAttributes, ReactNode } from "react";
2+
3+
export interface InputFieldProps extends InputHTMLAttributes<HTMLInputElement> {
4+
hasError?: boolean;
5+
errorMessage?: string;
6+
icon?: ReactNode;
7+
}

js/react/lib/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export * from "./components/contact-form";
55
export * from "./components/chip";
66
export * from "./components/tag";
77
export * from "./components/flap";
8+
export * from "./components/input";
89
export * from "./components/level";
910
export * from "./components/avatar";
1011
export * from "./components/collaborators";

js/react/showcase/App.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import {
55
Github,
66
Tag,
77
Telegram,
8+
Input,
9+
Location,
810
Flap,
911
Chip,
1012
Level,
@@ -524,6 +526,31 @@ export function App() {
524526
</div>
525527
</div>
526528
</ShowComponent>
529+
<ShowComponent
530+
title="Input"
531+
propsDef={{
532+
placeholder: {
533+
type: "string",
534+
default: "Input",
535+
},
536+
disabled: {
537+
type: "boolean",
538+
default: false,
539+
},
540+
hasError: {
541+
type: "boolean",
542+
default: false,
543+
},
544+
errorMessage: {
545+
type: "string",
546+
default: "Error",
547+
},
548+
}}
549+
component={Input}
550+
/>
551+
<ShowComponent title="Input With Icon">
552+
<Input icon={<Location />} placeholder="Input" />
553+
</ShowComponent>
527554
<ShowComponent title="Input Search">
528555
<div className="flex min-h-60 w-full flex-wrap justify-evenly gap-40 p-5">
529556
<InputSearch

styles/components.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
@import "./components/collaborators.css";
77
@import "./components/dropdown.css";
88
@import "./components/flap.css";
9+
@import "./components/input.css";
910
@import "./components/level.css";
1011
@import "./components/radio.css";
1112
@import "./components/tag.css";

styles/components/input-search.css

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
@layer components {
2-
3-
42
.rustlanges-input-search-container {
53
@apply relative flex h-fit w-full;
6-
4+
75
svg {
86
@apply text-gray-600 dark:text-gray-400;
97
}

styles/components/input.css

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
@layer components {
2+
.rustlanges-input {
3+
@apply flex items-center gap-2 rounded-xl px-[10px] py-3 transition-colors;
4+
@apply bg-light border-1 border-black text-black hover:bg-neutral-100;
5+
@apply dark:bg-neutral-950 dark:text-white dark:hover:bg-neutral-900;
6+
7+
&:has(> :active),
8+
&:has(> :focus) {
9+
@apply border-primary-500;
10+
}
11+
12+
@variant has-disabled {
13+
@apply cursor-not-allowed border-neutral-400 bg-neutral-100 text-neutral-600;
14+
@apply dark:bg-neutral-900 dark:text-neutral-400;
15+
}
16+
}
17+
18+
.rustlanges-input--error {
19+
@apply border-error-600;
20+
}
21+
22+
.rustlanges-input__container {
23+
@apply flex flex-col gap-1;
24+
}
25+
26+
.rustlanges-input__error {
27+
@apply text-error-800 dark:text-error-300 mt-1 text-sm;
28+
}
29+
30+
.rustlanges-input__inner {
31+
@apply w-full bg-transparent outline-none;
32+
@apply placeholder:text-neutral-600 dark:placeholder:text-neutral-400;
33+
@apply disabled:pointer-events-none disabled:placeholder:text-neutral-400 dark:disabled:placeholder:text-neutral-600;
34+
}
35+
36+
.rustlanges-input__icon {
37+
@apply text-neutral-600;
38+
39+
&:has(+ :disabled) {
40+
@apply text-neutral-400;
41+
}
42+
}
43+
}

0 commit comments

Comments
 (0)