@c-rex/ui 0.1.17 → 0.1.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c-rex/ui",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "src"
@@ -50,6 +50,10 @@
50
50
  "types": "./src/input.tsx",
51
51
  "import": "./src/input.tsx"
52
52
  },
53
+ "./input-group": {
54
+ "types": "./src/input-group.tsx",
55
+ "import": "./src/input-group.tsx"
56
+ },
53
57
  "./popover": {
54
58
  "types": "./src/popover.tsx",
55
59
  "import": "./src/popover.tsx"
@@ -186,6 +190,7 @@
186
190
  "clsx": "^2.1.1",
187
191
  "cmdk": "^1.1.1",
188
192
  "lucide-react": "^0.486.0",
193
+ "radix-ui": "^1.4.3",
189
194
  "react": "^18.3.1",
190
195
  "react-dom": "^18.3.1",
191
196
  "sonner": "^2.0.5",
@@ -0,0 +1,189 @@
1
+ import * as React from "react"
2
+ import { cva, type VariantProps } from "class-variance-authority"
3
+
4
+ import { cn } from "@c-rex/utils"
5
+ import { Button } from "./button"
6
+ import { Input } from "./input"
7
+ import { Textarea } from "./textarea"
8
+
9
+ const inputGroupVariants = cva(
10
+ "group/input-group relative flex w-full items-center rounded-md transition-[color,box-shadow] outline-none h-9 min-w-0 has-[>textarea]:h-auto",
11
+ {
12
+ variants: {
13
+ variant: {
14
+ default:
15
+ "border border-input bg-white",
16
+ embedded:
17
+ "border-0 bg-transparent shadow-none",
18
+ },
19
+ },
20
+ defaultVariants: {
21
+ variant: "default",
22
+ },
23
+ }
24
+ )
25
+
26
+ function InputGroup({
27
+ className,
28
+ variant,
29
+ ...props
30
+ }: React.ComponentProps<"div"> &
31
+ VariantProps<typeof inputGroupVariants>) {
32
+ return (
33
+ <div
34
+ data-slot="input-group"
35
+ role="group"
36
+ className={cn(
37
+ inputGroupVariants({ variant }),
38
+
39
+ // Variants based on alignment.
40
+ "has-[>[data-align=inline-start]]:[&>input]:pl-2",
41
+ "has-[>[data-align=inline-end]]:[&>input]:pr-2",
42
+ "has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3",
43
+ "has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3",
44
+
45
+ // Focus state.
46
+ "has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50",
47
+
48
+ // Error state.
49
+ "has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40",
50
+
51
+ className
52
+ )}
53
+ {...props}
54
+ />
55
+ )
56
+ }
57
+
58
+ const inputGroupAddonVariants = cva(
59
+ "text-muted-foreground flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium select-none [&>svg:not([class*='size-'])]:size-4 [&>kbd]:rounded-[calc(var(--radius)-5px)] group-data-[disabled=true]/input-group:opacity-50",
60
+ {
61
+ variants: {
62
+ align: {
63
+ "inline-start":
64
+ "order-first pl-3 has-[>button]:ml-[-0.45rem] has-[>kbd]:ml-[-0.35rem]",
65
+ "inline-end":
66
+ "order-last pr-3 has-[>button]:mr-[-0.45rem] has-[>kbd]:mr-[-0.35rem]",
67
+ "block-start":
68
+ "order-first w-full justify-start px-3 pt-3 [.border-b]:pb-3 group-has-[>input]/input-group:pt-2.5",
69
+ "block-end":
70
+ "order-last w-full justify-start px-3 pb-3 [.border-t]:pt-3 group-has-[>input]/input-group:pb-2.5",
71
+ },
72
+ },
73
+ defaultVariants: {
74
+ align: "inline-start",
75
+ },
76
+ }
77
+ )
78
+
79
+ function InputGroupAddon({
80
+ className,
81
+ align = "inline-start",
82
+ ...props
83
+ }: React.ComponentProps<"div"> & VariantProps<typeof inputGroupAddonVariants>) {
84
+ return (
85
+ <div
86
+ role="group"
87
+ data-slot="input-group-addon"
88
+ data-align={align}
89
+ className={cn(inputGroupAddonVariants({ align }), className)}
90
+ onClick={(e) => {
91
+ if ((e.target as HTMLElement).closest("button")) {
92
+ return
93
+ }
94
+ e.currentTarget.parentElement?.querySelector("input")?.focus()
95
+ }}
96
+ {...props}
97
+ />
98
+ )
99
+ }
100
+
101
+ const inputGroupButtonVariants = cva(
102
+ "text-sm shadow-none flex gap-2 items-center",
103
+ {
104
+ variants: {
105
+ size: {
106
+ xs: "h-6 gap-1 px-2 rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-3.5 has-[>svg]:px-2",
107
+ sm: "h-8 px-2.5 gap-1.5 rounded-md has-[>svg]:px-2.5",
108
+ "icon-xs":
109
+ "size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0",
110
+ "icon-sm": "size-8 p-0 has-[>svg]:p-0",
111
+ },
112
+ },
113
+ defaultVariants: {
114
+ size: "xs",
115
+ },
116
+ }
117
+ )
118
+
119
+ function InputGroupButton({
120
+ className,
121
+ type = "button",
122
+ variant = "ghost",
123
+ size = "xs",
124
+ ...props
125
+ }: Omit<React.ComponentProps<typeof Button>, "size"> &
126
+ VariantProps<typeof inputGroupButtonVariants>) {
127
+ return (
128
+ <Button
129
+ type={type}
130
+ data-size={size}
131
+ variant={variant}
132
+ className={cn(inputGroupButtonVariants({ size }), className)}
133
+ {...props}
134
+ />
135
+ )
136
+ }
137
+
138
+ function InputGroupText({ className, ...props }: React.ComponentProps<"span">) {
139
+ return (
140
+ <span
141
+ className={cn(
142
+ "text-muted-foreground flex items-center gap-2 text-sm [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
143
+ className
144
+ )}
145
+ {...props}
146
+ />
147
+ )
148
+ }
149
+
150
+ function InputGroupInput({
151
+ className,
152
+ ...props
153
+ }: React.ComponentProps<typeof Input>) {
154
+ return (
155
+ <Input
156
+ data-slot="input-group-control"
157
+ className={cn(
158
+ "flex-1 rounded-none border-0 bg-transparent shadow-none focus-visible:ring-0 dark:bg-transparent",
159
+ className
160
+ )}
161
+ {...props}
162
+ />
163
+ )
164
+ }
165
+
166
+ function InputGroupTextarea({
167
+ className,
168
+ ...props
169
+ }: React.ComponentProps<"textarea">) {
170
+ return (
171
+ <Textarea
172
+ data-slot="input-group-control"
173
+ className={cn(
174
+ "flex-1 resize-none rounded-none border-0 bg-transparent py-3 shadow-none focus-visible:ring-0 dark:bg-transparent",
175
+ className
176
+ )}
177
+ {...props}
178
+ />
179
+ )
180
+ }
181
+
182
+ export {
183
+ InputGroup,
184
+ InputGroupAddon,
185
+ InputGroupButton,
186
+ InputGroupText,
187
+ InputGroupInput,
188
+ InputGroupTextarea,
189
+ }
@@ -0,0 +1,18 @@
1
+ import * as React from "react"
2
+
3
+ import { cn } from "@c-rex/utils"
4
+
5
+ function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
6
+ return (
7
+ <textarea
8
+ data-slot="textarea"
9
+ className={cn(
10
+ "border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
11
+ className
12
+ )}
13
+ {...props}
14
+ />
15
+ )
16
+ }
17
+
18
+ export { Textarea }