Skip to content

Commit 1d3809d

Browse files
refactor: match InputGroup styling to original Lambda Curry aesthetic
Update InputGroup component styles to match the simpler, cleaner look of the original FieldPrefix/FieldSuffix implementation instead of shadcn's default styling. Changes: - Simplified InputGroup wrapper: removed shadow-xs, dark mode backgrounds, complex borders - Updated to use simple focus-within ring (matching original wrapper behavior) - Changed InputGroupAddon to use text-base (not text-sm) and gray-500/gray-700 colors - Added proper border styling: border-y + border-l/r for prefix/suffix - Simplified InputGroupText to just whitespace-nowrap (matching original) - Updated InputGroupInput to conditionally remove borders/radius based on addons Result: Inputs with prefix/suffix now match the original Lambda Curry design while using the official shadcn/ui component architecture underneath. Requested by: Jake Ruesink
1 parent afb156b commit 1d3809d

File tree

1 file changed

+23
-19
lines changed

1 file changed

+23
-19
lines changed

packages/components/src/ui/input-group.tsx

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,15 @@ function InputGroup({ className, ...props }: React.ComponentProps<'div'>) {
1515
data-slot="input-group"
1616
role="group"
1717
className={cn(
18-
'group/input-group border-input dark:bg-input/30 shadow-xs relative flex w-full min-w-0 items-center rounded-md border outline-none transition-[color,box-shadow]',
19-
'h-9 has-[>textarea]:h-auto',
18+
// Match original TextField wrapper styling: simple border with focus-within ring
19+
'group/input-group flex w-full rounded-md transition-all duration-200',
20+
'focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2 focus-within:ring-offset-background',
2021

21-
// Variants based on alignment.
22+
// Variants based on alignment - simplified to match original behavior
2223
'has-[>[data-align=inline-start]]:[&>input]:pl-2',
2324
'has-[>[data-align=inline-end]]:[&>input]:pr-2',
24-
'has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3',
25-
'has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3',
26-
27-
// Focus state.
28-
'has-[[data-slot=input-group-control]:focus-visible]:ring-ring has-[[data-slot=input-group-control]:focus-visible]:ring-1',
29-
30-
// Error state.
31-
'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',
25+
'has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-start]]:[&>input]:pb-3',
26+
'has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3',
3227

3328
className,
3429
)}
@@ -38,15 +33,18 @@ function InputGroup({ className, ...props }: React.ComponentProps<'div'>) {
3833
}
3934

4035
const inputGroupAddonVariants = cva(
41-
"text-muted-foreground flex h-auto cursor-text select-none items-center justify-center gap-2 py-1.5 text-sm font-medium group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4",
36+
// Match original FieldPrefix/FieldSuffix styling: simple borders with gray text
37+
'flex h-full text-base items-center text-gray-500 group-focus-within:text-gray-700 transition-colors duration-200 border-y border-input bg-background',
4238
{
4339
variants: {
4440
align: {
45-
'inline-start': 'order-first pl-3 has-[>button]:ml-[-0.45rem] has-[>kbd]:ml-[-0.35rem]',
46-
'inline-end': 'order-last pr-3 has-[>button]:mr-[-0.4rem] has-[>kbd]:mr-[-0.35rem]',
47-
'block-start':
48-
'[.border-b]:pb-3 order-first w-full justify-start px-3 pt-3 group-has-[>input]/input-group:pt-2.5',
49-
'block-end': '[.border-t]:pt-3 order-last w-full justify-start px-3 pb-3 group-has-[>input]/input-group:pb-2.5',
41+
// inline-start = prefix (left side)
42+
'inline-start': 'order-first pl-3 pr-0 border-l rounded-l-md',
43+
// inline-end = suffix (right side)
44+
'inline-end': 'order-last pr-3 pl-0 border-r rounded-r-md',
45+
// block alignment for advanced use cases
46+
'block-start': 'order-first w-full justify-start px-3 pt-3 pb-2',
47+
'block-end': 'order-last w-full justify-start px-3 pt-2 pb-3',
5048
},
5149
},
5250
defaultVariants: {
@@ -115,7 +113,8 @@ function InputGroupText({ className, ...props }: React.ComponentProps<'span'>) {
115113
return (
116114
<span
117115
className={cn(
118-
"text-muted-foreground flex items-center gap-2 text-sm [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none",
116+
// Match original FieldPrefix/FieldSuffix inner span: simple whitespace-nowrap
117+
'whitespace-nowrap',
119118
className,
120119
)}
121120
{...props}
@@ -128,7 +127,12 @@ function InputGroupInput({ className, ...props }: React.ComponentProps<'input'>)
128127
<TextInput
129128
data-slot="input-group-control"
130129
className={cn(
131-
'flex-1 rounded-none border-0 bg-transparent shadow-none focus-visible:ring-0 dark:bg-transparent',
130+
// Match original input styling but remove focus ring/offset (handled by wrapper)
131+
// Remove left border and radius if prefix exists, remove right if suffix exists
132+
'flex-1 focus-visible:ring-0 focus-visible:ring-offset-0 border-input',
133+
// Conditionally remove borders based on presence of addons
134+
'group-has-[>[data-align=inline-start]]:rounded-l-none group-has-[>[data-align=inline-start]]:border-l-0',
135+
'group-has-[>[data-align=inline-end]]:rounded-r-none group-has-[>[data-align=inline-end]]:border-r-0',
132136
className,
133137
)}
134138
{...props}

0 commit comments

Comments
 (0)