@c-rex/ui 0.1.18 → 0.1.20
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 +6 -1
- package/src/input-group.tsx +189 -0
- package/src/navigation-menu.tsx +9 -8
- package/src/textarea.tsx +18 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@c-rex/ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.20",
|
|
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
|
+
}
|
package/src/navigation-menu.tsx
CHANGED
|
@@ -58,10 +58,6 @@ function NavigationMenuItem({
|
|
|
58
58
|
)
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
const navigationMenuTriggerStyle = cva(
|
|
62
|
-
"group inline-flex h-9 w-max items-center justify-center rounded-full pl-4 pr-3 py-2 text-sm font-medium bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=open]:hover:bg-accent data-[state=open]:text-accent-foreground data-[state=open]:focus:bg-accent data-[state=open]:bg-accent/50 focus-visible:ring-ring/50 outline-none transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 "
|
|
63
|
-
)
|
|
64
|
-
|
|
65
61
|
function NavigationMenuTrigger({
|
|
66
62
|
className,
|
|
67
63
|
children,
|
|
@@ -70,7 +66,13 @@ function NavigationMenuTrigger({
|
|
|
70
66
|
return (
|
|
71
67
|
<NavigationMenuPrimitive.Trigger
|
|
72
68
|
data-slot="navigation-menu-trigger"
|
|
73
|
-
className={cn(
|
|
69
|
+
className={cn(
|
|
70
|
+
"group inline-flex h-9 w-max items-center justify-center rounded-full pl-4 pr-3 py-2 text-sm font-medium",
|
|
71
|
+
"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
|
|
72
|
+
"focus:bg-accent focus:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=open]:hover:bg-accent data-[state=open]:text-accent-foreground data-[state=open]:focus:bg-accent data-[state=open]:bg-accent/50 focus-visible:ring-ring/50 outline-none transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 ",
|
|
73
|
+
"group",
|
|
74
|
+
className
|
|
75
|
+
)}
|
|
74
76
|
{...props}
|
|
75
77
|
>
|
|
76
78
|
{children}{" "}
|
|
@@ -90,8 +92,8 @@ function NavigationMenuContent({
|
|
|
90
92
|
<NavigationMenuPrimitive.Content
|
|
91
93
|
data-slot="navigation-menu-content"
|
|
92
94
|
className={cn(
|
|
93
|
-
"data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 top-0
|
|
94
|
-
"group-data-[viewport=false]/navigation-menu:bg-popover group-data-[viewport=false]/navigation-menu:text-popover-foreground group-data-[viewport=false]/navigation-menu:data-[state=open]:animate-in group-data-[viewport=false]/navigation-menu:data-[state=closed]:animate-out group-data-[viewport=false]/navigation-menu:data-[state=closed]:zoom-out-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:zoom-in-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:fade-in-0 group-data-[viewport=false]/navigation-menu:data-[state=closed]:fade-out-0 group-data-[viewport=false]/navigation-menu:top-full group-data-[viewport=false]/navigation-menu:mt-1.5 group-data-[viewport=false]/navigation-menu:overflow-hidden group-data-[viewport=false]/navigation-menu:rounded-md group-data-[viewport=false]/navigation-menu:border group-data-[viewport=false]/navigation-menu:shadow group-data-[viewport=false]/navigation-menu:duration-200 **:data-[slot=navigation-menu-link]:focus:ring-0 **:data-[slot=navigation-menu-link]:focus:outline-none",
|
|
95
|
+
"data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 top-0 right-0 p-2 pr-2.5 absolute",
|
|
96
|
+
"group-data-[viewport=false]/navigation-menu:bg-popover group-data-[viewport=false]/navigation-menu:text-popover-foreground group-data-[viewport=false]/navigation-menu:data-[state=open]:animate-in group-data-[viewport=false]/navigation-menu:data-[state=closed]:animate-out group-data-[viewport=false]/navigation-menu:data-[state=closed]:zoom-out-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:zoom-in-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:fade-in-0 group-data-[viewport=false]/navigation-menu:data-[state=closed]:fade-out-0 group-data-[viewport=false]/navigation-menu:top-full group-data-[viewport=false]/navigation-menu:mt-1.5 group-data-[viewport=false]/navigation-menu:overflow-hidden group-data-[viewport=false]/navigation-menu:rounded-md group-data-[viewport=false]/navigation-menu:border group-data-[viewport=false]/navigation-menu:shadow group-data-[viewport=false]/navigation-menu:duration-200 **:data-[slot=navigation-menu-link]:focus:ring-0 **:data-[slot=navigation-menu-link]:focus:outline-none z-50",
|
|
95
97
|
className
|
|
96
98
|
)}
|
|
97
99
|
{...props}
|
|
@@ -164,5 +166,4 @@ export {
|
|
|
164
166
|
NavigationMenuLink,
|
|
165
167
|
NavigationMenuIndicator,
|
|
166
168
|
NavigationMenuViewport,
|
|
167
|
-
navigationMenuTriggerStyle,
|
|
168
169
|
}
|
package/src/textarea.tsx
ADDED
|
@@ -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 }
|