-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathInput.tsx
More file actions
107 lines (99 loc) · 3.7 KB
/
Input.tsx
File metadata and controls
107 lines (99 loc) · 3.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import * as React from "react";
import { useImperativeHandle, useRef } from "react";
import { cn } from "~/utils/cn";
import { Icon, type RenderIcon } from "./Icon";
const containerBase =
"has-[:focus-visible]:outline-none has-[:focus-visible]:ring-1 has-[:focus-visible]:ring-charcoal-650 has-[:focus-visible]:ring-offset-0 has-[:focus]:border-ring has-[:focus]:outline-none has-[:focus]:ring-1 has-[:focus]:ring-ring has-[:disabled]:cursor-not-allowed has-[:disabled]:opacity-50 ring-offset-background transition cursor-text";
const inputBase =
"h-full w-full text-text-bright bg-transparent file:border-0 file:bg-transparent file:text-base file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-0 disabled:cursor-not-allowed outline-none ring-0 border-none [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:m-0 [&::-webkit-inner-spin-button]:m-0 [&]:[-moz-appearance:textfield]";
const variants = {
large: {
container:
"px-1 w-full h-10 rounded-[3px] border border-charcoal-800 bg-charcoal-750 hover:border-charcoal-600 hover:bg-charcoal-650",
input: "px-2 text-sm",
iconSize: "size-4 ml-1",
accessory: "pr-1",
},
medium: {
container:
"px-1 h-8 w-full rounded border border-charcoal-800 bg-charcoal-750 hover:border-charcoal-600 hover:bg-charcoal-650",
input: "px-1.5 rounded text-sm",
iconSize: "size-4 ml-0.5",
accessory: "pr-1",
},
small: {
container:
"px-1 h-6 w-full rounded border border-charcoal-800 bg-charcoal-750 hover:border-charcoal-600 hover:bg-charcoal-650",
input: "px-1 rounded text-xs",
iconSize: "size-3 ml-0.5",
accessory: "pr-0.5",
},
tertiary: {
container: "px-1 h-6 w-full rounded hover:bg-charcoal-750",
input: "px-1 rounded text-xs",
iconSize: "size-3 ml-0.5",
accessory: "pr-0.5",
},
"secondary-small": {
container:
"px-1 h-6 w-full rounded border border-charcoal-600 hover:border-charcoal-550 bg-grid-dimmed hover:bg-charcoal-650",
input: "px-1 rounded text-xs",
iconSize: "size-3 ml-0.5",
accessory: "pr-0.5",
},
};
export type InputProps = React.InputHTMLAttributes<HTMLInputElement> & {
variant?: keyof typeof variants;
icon?: RenderIcon;
accessory?: React.ReactNode;
fullWidth?: boolean;
containerClassName?: string;
};
const Input = React.forwardRef<HTMLInputElement, InputProps>(
(
{
className,
type,
accessory,
fullWidth = true,
variant = "medium",
icon,
containerClassName,
...props
},
ref
) => {
const innerRef = useRef<HTMLInputElement>(null);
useImperativeHandle(ref, () => innerRef.current as HTMLInputElement);
const variantContainerClassName = variants[variant].container;
const inputClassName = variants[variant].input;
const iconClassName = variants[variant].iconSize;
return (
<div
className={cn(
"flex items-center",
containerBase,
variantContainerClassName,
containerClassName,
fullWidth ? "w-full" : "max-w-max"
)}
onClick={() => innerRef.current && innerRef.current.focus()}
>
{icon && (
<div className="pointer-events-none flex items-center">
<Icon icon={icon} className={cn(iconClassName, "text-text-dimmed")} />
</div>
)}
<input
type={type}
className={cn("grow", inputBase, inputClassName, className)}
ref={innerRef}
{...props}
/>
{accessory && <div className={cn(variants[variant].accessory)}>{accessory}</div>}
</div>
);
}
);
Input.displayName = "Input";
export { Input };