Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
3e900fb
feat: remove gray background from SearchInput affix
ArtemKhvorostianyi May 28, 2026
66a230c
feat: remove gray bg in all inputs
ArtemKhvorostianyi May 29, 2026
cea552d
feat: keep suffixes and affixes styling in consistency
ArtemKhvorostianyi May 29, 2026
b22b0fb
feat: add suffix and affix support for text area variant
ArtemKhvorostianyi May 29, 2026
4cdf2f9
feat: hide test app
ArtemKhvorostianyi May 29, 2026
6afa090
feat: keep icons gaps in consistency
ArtemKhvorostianyi May 30, 2026
1186338
feat: keep icons gaps in consistency
ArtemKhvorostianyi May 30, 2026
94a7fe5
feat: handle icons gaps in different densities
ArtemKhvorostianyi May 30, 2026
3b3c290
feat: fix borders for text area and password, improve sizing of suffi…
ArtemKhvorostianyi May 30, 2026
3fed384
feat: keep number input design in consistency with text inputs
ArtemKhvorostianyi May 30, 2026
5da468a
feat: keep select input design in consistency with other inputs
ArtemKhvorostianyi May 30, 2026
f87564e
feat: handle bool densities and suffixes, icons gaps
ArtemKhvorostianyi May 31, 2026
8e726a1
feat: enhance gaps
ArtemKhvorostianyi May 31, 2026
ac4d83c
feat: keep gaps and sizes in consistency with other inputs
ArtemKhvorostianyi May 31, 2026
2123a27
feat: keep gaps and sizes in consistency
ArtemKhvorostianyi May 31, 2026
d29f87a
feat: keep gaps and sizes in consistency with other inputs
ArtemKhvorostianyi May 31, 2026
81bfc83
feat: keep gaps and sizes in consistency
ArtemKhvorostianyi May 31, 2026
ea625ec
feat: keep gaps and sizes in consistenty
ArtemKhvorostianyi May 31, 2026
76abb3c
Merge branch 'development' into 4502-remove-gray-background-from-sear…
ArtemKhvorostianyi May 31, 2026
fedad9d
feat: update tests
ArtemKhvorostianyi May 31, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
901 changes: 901 additions & 0 deletions src/Ivy.Samples.Shared/Apps/Tests/InputAffixesGalleryApp.cs

Large diffs are not rendered by default.

7 changes: 1 addition & 6 deletions src/Ivy.Samples.Shared/Apps/Widgets/Inputs/TextInputApp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -274,11 +274,6 @@ public override object Build()
| Text.Monospaced("Nullable with prefix/suffix")
| nullableState.ToTextInput().Prefix("$").Placeholder("Amount")
| nullableState.ToTextInput().Suffix("%").Placeholder("Percentage")
| nullableState.ToTextInput().Prefix("https://").Suffix(".com").Placeholder("domain")

| Text.Monospaced("Nullable + Invalid + ShortcutKey")
| nullableState.ToTextInput().Prefix("@").Invalid("Required field").ShortcutKey("Ctrl+P")
| nullableState.ToTextInput().Suffix(Icons.Search).Invalid("Invalid input").ShortcutKey("Ctrl+F")
| nullableState.ToTextInput().Prefix(Icons.Mail).Suffix(".com").Invalid("Error").ShortcutKey("Ctrl+B");
| nullableState.ToTextInput().Prefix("https://").Suffix(".com").Placeholder("domain");
}
}
34 changes: 24 additions & 10 deletions src/frontend/src/components/InvalidIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,32 @@ import { InfoIcon } from "lucide-react";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./ui/tooltip";
import { cn } from "@/lib/utils";

export const InvalidIcon: React.FC<{ message: string; className?: string }> = ({
message,
className,
}) => {
export const InvalidIcon: React.FC<{
message: string;
className?: string;
iconClassName?: string;
}> = ({ message, className, iconClassName }) => {
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger
className={cn(className, "cursor-pointer pointer-events-auto")}
data-invalid-icon="true"
>
<InfoIcon className="size-4 text-red-900 hover:text-red-400 transition-colors duration-200" />
<Tooltip className="contents">
<TooltipTrigger asChild>
<button
type="button"
tabIndex={-1}
data-invalid-icon="true"
className={cn(
"inline-flex shrink-0 cursor-pointer items-center justify-center border-0 bg-transparent p-0 shadow-none outline-none leading-none",
"pointer-events-auto focus-visible:ring-1 focus-visible:ring-ring",
className,
)}
>
<InfoIcon
className={cn(
"block shrink-0 text-red-900 transition-colors duration-200 hover:text-red-400",
iconClassName ?? "size-4",
)}
/>
</button>
</TooltipTrigger>
<TooltipContent className="bg-popover text-popover-foreground shadow-md">
<div className="max-w-60">{message}</div>
Expand Down
14 changes: 14 additions & 0 deletions src/frontend/src/components/ui/input/bool-input-variant.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
import { cva } from "class-variance-authority";

/** Gap between control and label — scales with density. */
export const boolInputControlGapVariant = cva("", {
variants: {
density: {
Small: "gap-1.5",
Medium: "gap-2",
Large: "gap-2.5",
},
},
defaultVariants: {
density: "Medium",
},
});

// Row min-height variants - matches TextInput heights for consistent form field alignment
export const boolInputRowMinHeightVariant = cva("", {
variants: {
Expand Down
14 changes: 14 additions & 0 deletions src/frontend/src/components/ui/input/color-input-variant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,20 @@ export const colorInputVariant = cva(
},
);

/** Affix row min-height — matches bool/text field heights. */
export const colorInputRowMinHeightVariant = cva("", {
variants: {
density: {
Small: "min-h-7",
Medium: "min-h-9",
Large: "min-h-11",
},
},
defaultVariants: {
density: "Medium",
},
});

export const colorInputPickerVariant = cva("", {
variants: {
density: {
Expand Down
16 changes: 8 additions & 8 deletions src/frontend/src/components/ui/input/date-range-input-variant.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { cva } from "class-variance-authority";

export const dateRangeInputVariant = cva(
"w-full justify-start text-left font-normal pr-20 cursor-pointer bg-transparent",
"w-full justify-start text-left font-normal cursor-pointer bg-transparent",
{
variants: {
density: {
Small: "h-8 px-3",
Medium: "h-9 px-4 py-2",
Large: "h-10 px-5 py-2",
Small: "h-7 min-h-7 max-h-7 px-2 py-0 text-xs [&_svg]:!size-3",
Medium: "h-9 min-h-9 max-h-9 px-3 py-0 text-sm [&_svg]:!size-4",
Large: "h-11 min-h-11 max-h-11 px-4 py-0 text-base [&_svg]:!size-5",
},
},
defaultVariants: {
Expand All @@ -16,12 +16,12 @@ export const dateRangeInputVariant = cva(
},
);

export const dateRangeInputIconVariant = cva("", {
export const dateRangeInputIconVariant = cva("shrink-0", {
variants: {
density: {
Small: "size-3",
Medium: "size-4",
Large: "size-5",
Small: "!size-3",
Medium: "!size-4",
Large: "!size-5",
},
},
defaultVariants: {
Expand Down
10 changes: 5 additions & 5 deletions src/frontend/src/components/ui/input/date-time-input-variant.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { cva } from "class-variance-authority";

export const dateTimeInputVariant = cva(
"w-full justify-start text-left font-normal pr-20 cursor-pointer bg-transparent",
"w-full justify-start text-left font-normal cursor-pointer bg-transparent",
{
variants: {
density: {
Small: "h-7 px-2 text-xs",
Medium: "h-9 px-3 py-2 text-sm",
Large: "h-11 px-4 py-2 text-base",
Small: "h-7 min-h-7 max-h-7 px-2 py-0 text-xs [&_svg]:!size-3",
Medium: "h-9 min-h-9 max-h-9 px-3 py-0 text-sm [&_svg]:!size-4",
Large: "h-11 min-h-11 max-h-11 px-4 py-0 text-base [&_svg]:!size-5",
},
},
defaultVariants: {
Expand All @@ -16,7 +16,7 @@ export const dateTimeInputVariant = cva(
},
);

export const dateTimeInputIconVariant = cva("", {
export const dateTimeInputIconVariant = cva("shrink-0", {
variants: {
density: {
Small: "!size-3",
Expand Down
17 changes: 17 additions & 0 deletions src/frontend/src/components/ui/input/icon-input-variant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,23 @@ export const iconInputTriggerVariant = cva(
},
);

/** Trigger inside affix shell — heights match textInputSizeVariant (h-7 / h-9 / h-11). */
export const iconInputAffixTriggerVariant = cva(
"justify-start font-normal min-w-0 max-w-none rounded-none border-0 bg-transparent px-0! py-0! shadow-none dark:border-transparent dark:bg-transparent",
{
variants: {
density: {
Small: "h-7 text-xs",
Medium: "h-9 text-sm",
Large: "h-11 text-base",
},
},
defaultVariants: {
density: "Medium",
},
},
);

export const iconInputIconVariant = cva("", {
variants: {
density: {
Expand Down
Loading
Loading