@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c-rex/ui",
3
- "version": "0.1.18",
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
+ }
@@ -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(navigationMenuTriggerStyle(), "group", className)}
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 left-0 w-full p-2 pr-2.5 md:absolute md:w-auto",
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
  }
@@ -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 }