mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-06-24 21:25:55 +00:00
feat: add input-group
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Input Group
|
||||
description: Display additional information or actions to an input or textarea.
|
||||
description: Add addons, buttons, and helper content to inputs.
|
||||
base: base
|
||||
component: true
|
||||
---
|
||||
@@ -10,7 +10,7 @@ import { IconInfoCircle } from "@tabler/icons-react"
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-demo"
|
||||
className="[&_.preview]:p-4"
|
||||
previewClassName="h-[26rem]"
|
||||
/>
|
||||
|
||||
## Installation
|
||||
@@ -68,12 +68,59 @@ import {
|
||||
<InputGroupAddon>
|
||||
<SearchIcon />
|
||||
</InputGroupAddon>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupButton>Search</InputGroupButton>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
```
|
||||
|
||||
## Align
|
||||
|
||||
Use the `align` prop on `InputGroupAddon` to position the addon relative to the input.
|
||||
|
||||
<Callout>
|
||||
For proper focus management, `InputGroupAddon` should always be placed after
|
||||
`InputGroupInput` or `InputGroupTextarea` in the DOM. Use the `align` prop to
|
||||
visually position the addon.
|
||||
</Callout>
|
||||
|
||||
### inline-start
|
||||
|
||||
Use `align="inline-start"` to position the addon at the start of the input. This is the default.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-inline-start"
|
||||
previewClassName="h-48"
|
||||
/>
|
||||
|
||||
### inline-end
|
||||
|
||||
Use `align="inline-end"` to position the addon at the end of the input.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-inline-end"
|
||||
previewClassName="h-48"
|
||||
/>
|
||||
|
||||
### block-start
|
||||
|
||||
Use `align="block-start"` to position the addon above the input.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-block-start"
|
||||
previewClassName="h-96"
|
||||
/>
|
||||
|
||||
### block-end
|
||||
|
||||
Use `align="block-end"` to position the addon below the input.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-block-end"
|
||||
previewClassName="h-[26rem]"
|
||||
/>
|
||||
|
||||
## Examples
|
||||
|
||||
### Icon
|
||||
@@ -81,119 +128,69 @@ import {
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-icon"
|
||||
className="[&_.preview]:p-4"
|
||||
previewClassName="h-80"
|
||||
/>
|
||||
|
||||
### Text
|
||||
|
||||
Display additional text information alongside inputs.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-text"
|
||||
className="[&_.preview]:p-4"
|
||||
previewClassName="h-80"
|
||||
/>
|
||||
|
||||
### Button
|
||||
|
||||
Add buttons to perform actions within the input group.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-button"
|
||||
className="[&_.preview]:p-4"
|
||||
previewClassName="h-72"
|
||||
/>
|
||||
|
||||
### Tooltip
|
||||
|
||||
Add tooltips to provide additional context or help.
|
||||
### Kbd
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-tooltip"
|
||||
className="[&_.preview]:p-4"
|
||||
/>
|
||||
|
||||
### Textarea
|
||||
|
||||
Input groups also work with textarea components. Use `block-start` or `block-end` for alignment.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-textarea"
|
||||
className="[&_.preview]:p-4"
|
||||
/>
|
||||
|
||||
### Spinner
|
||||
|
||||
Show loading indicators while processing input.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-spinner"
|
||||
className="[&_.preview]:p-4"
|
||||
/>
|
||||
|
||||
### Label
|
||||
|
||||
Add labels within input groups to improve accessibility.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-label"
|
||||
className="[&_.preview]:p-4"
|
||||
name="input-group-kbd"
|
||||
previewClassName="h-40"
|
||||
/>
|
||||
|
||||
### Dropdown
|
||||
|
||||
Pair input groups with dropdown menus for complex interactions.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-dropdown"
|
||||
className="[&_.preview]:p-4"
|
||||
previewClassName="h-56"
|
||||
/>
|
||||
|
||||
### Button Group
|
||||
|
||||
Wrap input groups with button groups to create prefixes and suffixes.
|
||||
### Spinner
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-button-group"
|
||||
className="[&_.preview]:p-4"
|
||||
name="input-group-spinner"
|
||||
previewClassName="h-80"
|
||||
/>
|
||||
|
||||
### Textarea
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-textarea"
|
||||
previewClassName="h-96"
|
||||
/>
|
||||
|
||||
### Custom Input
|
||||
|
||||
Add the `data-slot="input-group-control"` attribute to your custom input for automatic behavior and focus state handling.
|
||||
Add the `data-slot="input-group-control"` attribute to your custom input for automatic focus state handling.
|
||||
|
||||
No style is applied to the custom input. Apply your own styles using the `className` prop.
|
||||
Here's an example of a custom resizable textarea from a third-party library.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-custom"
|
||||
className="!mb-4 [&_.preview]:p-4"
|
||||
previewClassName="h-56"
|
||||
/>
|
||||
|
||||
```tsx showLineNumbers
|
||||
import { InputGroup, InputGroupAddon } from "@/component/ui/input-group"
|
||||
import TextareaAutosize from "react-textarea-autosize"
|
||||
|
||||
export function InputGroupCustom() {
|
||||
return (
|
||||
<InputGroup>
|
||||
<TextareaAutosize
|
||||
data-slot="input-group-control"
|
||||
className="dark:bg-input/30 flex field-sizing-content min-h-16 w-full resize-none rounded-md bg-transparent px-3 py-2 text-base transition-[color,box-shadow] outline-none"
|
||||
placeholder="Autoresize textarea..."
|
||||
/>
|
||||
<InputGroupAddon align="block-end">how</InputGroupAddon>
|
||||
</InputGroup>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### InputGroup
|
||||
@@ -297,8 +294,3 @@ All other props are passed through to the underlying `<Textarea />` component.
|
||||
</InputGroup>
|
||||
```
|
||||
|
||||
## Changelog
|
||||
|
||||
### 2025-10-06 `InputGroup`
|
||||
|
||||
Add the `min-w-0` class to the `InputGroup` component. See [diff](https://github.com/shadcn-ui/ui/pull/8341/files#diff-0e2ee95d0050ca4c5d82339df86c54e14a6739dc4638fdda0eec8f73aebc2da9).
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Input Group
|
||||
description: Display additional information or actions to an input or textarea.
|
||||
description: Add addons, buttons, and helper content to inputs.
|
||||
base: radix
|
||||
component: true
|
||||
---
|
||||
@@ -10,7 +10,7 @@ import { IconInfoCircle } from "@tabler/icons-react"
|
||||
<ComponentPreview
|
||||
styleName="radix-nova"
|
||||
name="input-group-demo"
|
||||
className="[&_.preview]:p-4"
|
||||
previewClassName="h-[26rem]"
|
||||
/>
|
||||
|
||||
## Installation
|
||||
@@ -68,12 +68,59 @@ import {
|
||||
<InputGroupAddon>
|
||||
<SearchIcon />
|
||||
</InputGroupAddon>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupButton>Search</InputGroupButton>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
```
|
||||
|
||||
## Align
|
||||
|
||||
Use the `align` prop on `InputGroupAddon` to position the addon relative to the input.
|
||||
|
||||
<Callout>
|
||||
For proper focus management, `InputGroupAddon` should always be placed after
|
||||
`InputGroupInput` or `InputGroupTextarea` in the DOM. Use the `align` prop to
|
||||
visually position the addon.
|
||||
</Callout>
|
||||
|
||||
### inline-start
|
||||
|
||||
Use `align="inline-start"` to position the addon at the start of the input. This is the default.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="radix-nova"
|
||||
name="input-group-inline-start"
|
||||
previewClassName="h-48"
|
||||
/>
|
||||
|
||||
### inline-end
|
||||
|
||||
Use `align="inline-end"` to position the addon at the end of the input.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="radix-nova"
|
||||
name="input-group-inline-end"
|
||||
previewClassName="h-48"
|
||||
/>
|
||||
|
||||
### block-start
|
||||
|
||||
Use `align="block-start"` to position the addon above the input.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="radix-nova"
|
||||
name="input-group-block-start"
|
||||
previewClassName="h-96"
|
||||
/>
|
||||
|
||||
### block-end
|
||||
|
||||
Use `align="block-end"` to position the addon below the input.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="radix-nova"
|
||||
name="input-group-block-end"
|
||||
previewClassName="h-[26rem]"
|
||||
/>
|
||||
|
||||
## Examples
|
||||
|
||||
### Icon
|
||||
@@ -81,119 +128,69 @@ import {
|
||||
<ComponentPreview
|
||||
styleName="radix-nova"
|
||||
name="input-group-icon"
|
||||
className="[&_.preview]:p-4"
|
||||
previewClassName="h-80"
|
||||
/>
|
||||
|
||||
### Text
|
||||
|
||||
Display additional text information alongside inputs.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="radix-nova"
|
||||
name="input-group-text"
|
||||
className="[&_.preview]:p-4"
|
||||
previewClassName="h-80"
|
||||
/>
|
||||
|
||||
### Button
|
||||
|
||||
Add buttons to perform actions within the input group.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="radix-nova"
|
||||
name="input-group-button"
|
||||
className="[&_.preview]:p-4"
|
||||
previewClassName="h-72"
|
||||
/>
|
||||
|
||||
### Tooltip
|
||||
|
||||
Add tooltips to provide additional context or help.
|
||||
### Kbd
|
||||
|
||||
<ComponentPreview
|
||||
styleName="radix-nova"
|
||||
name="input-group-tooltip"
|
||||
className="[&_.preview]:p-4"
|
||||
/>
|
||||
|
||||
### Textarea
|
||||
|
||||
Input groups also work with textarea components. Use `block-start` or `block-end` for alignment.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="radix-nova"
|
||||
name="input-group-textarea"
|
||||
className="[&_.preview]:p-4"
|
||||
/>
|
||||
|
||||
### Spinner
|
||||
|
||||
Show loading indicators while processing input.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="radix-nova"
|
||||
name="input-group-spinner"
|
||||
className="[&_.preview]:p-4"
|
||||
/>
|
||||
|
||||
### Label
|
||||
|
||||
Add labels within input groups to improve accessibility.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="radix-nova"
|
||||
name="input-group-label"
|
||||
className="[&_.preview]:p-4"
|
||||
name="input-group-kbd"
|
||||
previewClassName="h-40"
|
||||
/>
|
||||
|
||||
### Dropdown
|
||||
|
||||
Pair input groups with dropdown menus for complex interactions.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="radix-nova"
|
||||
name="input-group-dropdown"
|
||||
className="[&_.preview]:p-4"
|
||||
previewClassName="h-56"
|
||||
/>
|
||||
|
||||
### Button Group
|
||||
|
||||
Wrap input groups with button groups to create prefixes and suffixes.
|
||||
### Spinner
|
||||
|
||||
<ComponentPreview
|
||||
styleName="radix-nova"
|
||||
name="input-group-button-group"
|
||||
className="[&_.preview]:p-4"
|
||||
name="input-group-spinner"
|
||||
previewClassName="h-80"
|
||||
/>
|
||||
|
||||
### Textarea
|
||||
|
||||
<ComponentPreview
|
||||
styleName="radix-nova"
|
||||
name="input-group-textarea"
|
||||
previewClassName="h-96"
|
||||
/>
|
||||
|
||||
### Custom Input
|
||||
|
||||
Add the `data-slot="input-group-control"` attribute to your custom input for automatic behavior and focus state handling.
|
||||
Add the `data-slot="input-group-control"` attribute to your custom input for automatic focus state handling.
|
||||
|
||||
No style is applied to the custom input. Apply your own styles using the `className` prop.
|
||||
Here's an example of a custom resizable textarea from a third-party library.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="radix-nova"
|
||||
name="input-group-custom"
|
||||
className="!mb-4 [&_.preview]:p-4"
|
||||
previewClassName="h-56"
|
||||
/>
|
||||
|
||||
```tsx showLineNumbers
|
||||
import { InputGroup, InputGroupAddon } from "@/component/ui/input-group"
|
||||
import TextareaAutosize from "react-textarea-autosize"
|
||||
|
||||
export function InputGroupCustom() {
|
||||
return (
|
||||
<InputGroup>
|
||||
<TextareaAutosize
|
||||
data-slot="input-group-control"
|
||||
className="dark:bg-input/30 flex field-sizing-content min-h-16 w-full resize-none rounded-md bg-transparent px-3 py-2 text-base transition-[color,box-shadow] outline-none"
|
||||
placeholder="Autoresize textarea..."
|
||||
/>
|
||||
<InputGroupAddon align="block-end">how</InputGroupAddon>
|
||||
</InputGroup>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### InputGroup
|
||||
|
||||
@@ -2553,6 +2553,32 @@ export const ExamplesIndex: Record<string, Record<string, any>> = {
|
||||
return { default: mod.default || mod[exportName] }
|
||||
}),
|
||||
},
|
||||
"input-group-block-end": {
|
||||
name: "input-group-block-end",
|
||||
filePath: "examples/radix/input-group-block-end.tsx",
|
||||
component: React.lazy(async () => {
|
||||
const mod = await import("./radix/input-group-block-end")
|
||||
const exportName =
|
||||
Object.keys(mod).find(
|
||||
(key) =>
|
||||
typeof mod[key] === "function" || typeof mod[key] === "object"
|
||||
) || "input-group-block-end"
|
||||
return { default: mod.default || mod[exportName] }
|
||||
}),
|
||||
},
|
||||
"input-group-block-start": {
|
||||
name: "input-group-block-start",
|
||||
filePath: "examples/radix/input-group-block-start.tsx",
|
||||
component: React.lazy(async () => {
|
||||
const mod = await import("./radix/input-group-block-start")
|
||||
const exportName =
|
||||
Object.keys(mod).find(
|
||||
(key) =>
|
||||
typeof mod[key] === "function" || typeof mod[key] === "object"
|
||||
) || "input-group-block-start"
|
||||
return { default: mod.default || mod[exportName] }
|
||||
}),
|
||||
},
|
||||
"input-group-button-group": {
|
||||
name: "input-group-button-group",
|
||||
filePath: "examples/radix/input-group-button-group.tsx",
|
||||
@@ -2644,6 +2670,45 @@ export const ExamplesIndex: Record<string, Record<string, any>> = {
|
||||
return { default: mod.default || mod[exportName] }
|
||||
}),
|
||||
},
|
||||
"input-group-inline-end": {
|
||||
name: "input-group-inline-end",
|
||||
filePath: "examples/radix/input-group-inline-end.tsx",
|
||||
component: React.lazy(async () => {
|
||||
const mod = await import("./radix/input-group-inline-end")
|
||||
const exportName =
|
||||
Object.keys(mod).find(
|
||||
(key) =>
|
||||
typeof mod[key] === "function" || typeof mod[key] === "object"
|
||||
) || "input-group-inline-end"
|
||||
return { default: mod.default || mod[exportName] }
|
||||
}),
|
||||
},
|
||||
"input-group-inline-start": {
|
||||
name: "input-group-inline-start",
|
||||
filePath: "examples/radix/input-group-inline-start.tsx",
|
||||
component: React.lazy(async () => {
|
||||
const mod = await import("./radix/input-group-inline-start")
|
||||
const exportName =
|
||||
Object.keys(mod).find(
|
||||
(key) =>
|
||||
typeof mod[key] === "function" || typeof mod[key] === "object"
|
||||
) || "input-group-inline-start"
|
||||
return { default: mod.default || mod[exportName] }
|
||||
}),
|
||||
},
|
||||
"input-group-kbd": {
|
||||
name: "input-group-kbd",
|
||||
filePath: "examples/radix/input-group-kbd.tsx",
|
||||
component: React.lazy(async () => {
|
||||
const mod = await import("./radix/input-group-kbd")
|
||||
const exportName =
|
||||
Object.keys(mod).find(
|
||||
(key) =>
|
||||
typeof mod[key] === "function" || typeof mod[key] === "object"
|
||||
) || "input-group-kbd"
|
||||
return { default: mod.default || mod[exportName] }
|
||||
}),
|
||||
},
|
||||
"input-group-label": {
|
||||
name: "input-group-label",
|
||||
filePath: "examples/radix/input-group-label.tsx",
|
||||
@@ -8862,6 +8927,32 @@ export const ExamplesIndex: Record<string, Record<string, any>> = {
|
||||
return { default: mod.default || mod[exportName] }
|
||||
}),
|
||||
},
|
||||
"input-group-block-end": {
|
||||
name: "input-group-block-end",
|
||||
filePath: "examples/base/input-group-block-end.tsx",
|
||||
component: React.lazy(async () => {
|
||||
const mod = await import("./base/input-group-block-end")
|
||||
const exportName =
|
||||
Object.keys(mod).find(
|
||||
(key) =>
|
||||
typeof mod[key] === "function" || typeof mod[key] === "object"
|
||||
) || "input-group-block-end"
|
||||
return { default: mod.default || mod[exportName] }
|
||||
}),
|
||||
},
|
||||
"input-group-block-start": {
|
||||
name: "input-group-block-start",
|
||||
filePath: "examples/base/input-group-block-start.tsx",
|
||||
component: React.lazy(async () => {
|
||||
const mod = await import("./base/input-group-block-start")
|
||||
const exportName =
|
||||
Object.keys(mod).find(
|
||||
(key) =>
|
||||
typeof mod[key] === "function" || typeof mod[key] === "object"
|
||||
) || "input-group-block-start"
|
||||
return { default: mod.default || mod[exportName] }
|
||||
}),
|
||||
},
|
||||
"input-group-button-group": {
|
||||
name: "input-group-button-group",
|
||||
filePath: "examples/base/input-group-button-group.tsx",
|
||||
@@ -8953,6 +9044,45 @@ export const ExamplesIndex: Record<string, Record<string, any>> = {
|
||||
return { default: mod.default || mod[exportName] }
|
||||
}),
|
||||
},
|
||||
"input-group-inline-end": {
|
||||
name: "input-group-inline-end",
|
||||
filePath: "examples/base/input-group-inline-end.tsx",
|
||||
component: React.lazy(async () => {
|
||||
const mod = await import("./base/input-group-inline-end")
|
||||
const exportName =
|
||||
Object.keys(mod).find(
|
||||
(key) =>
|
||||
typeof mod[key] === "function" || typeof mod[key] === "object"
|
||||
) || "input-group-inline-end"
|
||||
return { default: mod.default || mod[exportName] }
|
||||
}),
|
||||
},
|
||||
"input-group-inline-start": {
|
||||
name: "input-group-inline-start",
|
||||
filePath: "examples/base/input-group-inline-start.tsx",
|
||||
component: React.lazy(async () => {
|
||||
const mod = await import("./base/input-group-inline-start")
|
||||
const exportName =
|
||||
Object.keys(mod).find(
|
||||
(key) =>
|
||||
typeof mod[key] === "function" || typeof mod[key] === "object"
|
||||
) || "input-group-inline-start"
|
||||
return { default: mod.default || mod[exportName] }
|
||||
}),
|
||||
},
|
||||
"input-group-kbd": {
|
||||
name: "input-group-kbd",
|
||||
filePath: "examples/base/input-group-kbd.tsx",
|
||||
component: React.lazy(async () => {
|
||||
const mod = await import("./base/input-group-kbd")
|
||||
const exportName =
|
||||
Object.keys(mod).find(
|
||||
(key) =>
|
||||
typeof mod[key] === "function" || typeof mod[key] === "object"
|
||||
) || "input-group-kbd"
|
||||
return { default: mod.default || mod[exportName] }
|
||||
}),
|
||||
},
|
||||
"input-group-label": {
|
||||
name: "input-group-label",
|
||||
filePath: "examples/base/input-group-label.tsx",
|
||||
|
||||
49
apps/v4/examples/base/input-group-block-end.tsx
Normal file
49
apps/v4/examples/base/input-group-block-end.tsx
Normal file
@@ -0,0 +1,49 @@
|
||||
import {
|
||||
Field,
|
||||
FieldDescription,
|
||||
FieldGroup,
|
||||
FieldLabel,
|
||||
} from "@/examples/base/ui/field"
|
||||
import {
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupButton,
|
||||
InputGroupInput,
|
||||
InputGroupText,
|
||||
InputGroupTextarea,
|
||||
} from "@/examples/base/ui/input-group"
|
||||
|
||||
export function InputGroupBlockEnd() {
|
||||
return (
|
||||
<FieldGroup className="max-w-sm">
|
||||
<Field>
|
||||
<FieldLabel htmlFor="block-end-input">Input</FieldLabel>
|
||||
<InputGroup className="h-auto">
|
||||
<InputGroupInput id="block-end-input" placeholder="Enter amount" />
|
||||
<InputGroupAddon align="block-end">
|
||||
<InputGroupText>USD</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<FieldDescription>Footer positioned below the input.</FieldDescription>
|
||||
</Field>
|
||||
<Field>
|
||||
<FieldLabel htmlFor="block-end-textarea">Textarea</FieldLabel>
|
||||
<InputGroup>
|
||||
<InputGroupTextarea
|
||||
id="block-end-textarea"
|
||||
placeholder="Write a comment..."
|
||||
/>
|
||||
<InputGroupAddon align="block-end">
|
||||
<InputGroupText>0/280</InputGroupText>
|
||||
<InputGroupButton variant="default" size="sm" className="ml-auto">
|
||||
Post
|
||||
</InputGroupButton>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<FieldDescription>
|
||||
Footer positioned below the textarea.
|
||||
</FieldDescription>
|
||||
</Field>
|
||||
</FieldGroup>
|
||||
)
|
||||
}
|
||||
56
apps/v4/examples/base/input-group-block-start.tsx
Normal file
56
apps/v4/examples/base/input-group-block-start.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import {
|
||||
Field,
|
||||
FieldDescription,
|
||||
FieldGroup,
|
||||
FieldLabel,
|
||||
} from "@/examples/base/ui/field"
|
||||
import {
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupButton,
|
||||
InputGroupInput,
|
||||
InputGroupText,
|
||||
InputGroupTextarea,
|
||||
} from "@/examples/base/ui/input-group"
|
||||
import { CopyIcon, FileCodeIcon } from "lucide-react"
|
||||
|
||||
export function InputGroupBlockStart() {
|
||||
return (
|
||||
<FieldGroup className="max-w-sm">
|
||||
<Field>
|
||||
<FieldLabel htmlFor="block-start-input">Input</FieldLabel>
|
||||
<InputGroup className="h-auto">
|
||||
<InputGroupInput
|
||||
id="block-start-input"
|
||||
placeholder="Enter your name"
|
||||
/>
|
||||
<InputGroupAddon align="block-start">
|
||||
<InputGroupText>Full Name</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<FieldDescription>Header positioned above the input.</FieldDescription>
|
||||
</Field>
|
||||
<Field>
|
||||
<FieldLabel htmlFor="block-start-textarea">Textarea</FieldLabel>
|
||||
<InputGroup>
|
||||
<InputGroupTextarea
|
||||
id="block-start-textarea"
|
||||
placeholder="console.log('Hello, world!');"
|
||||
className="font-mono text-sm"
|
||||
/>
|
||||
<InputGroupAddon align="block-start">
|
||||
<FileCodeIcon className="text-muted-foreground" />
|
||||
<InputGroupText className="font-mono">script.js</InputGroupText>
|
||||
<InputGroupButton size="icon-xs" className="ml-auto">
|
||||
<CopyIcon />
|
||||
<span className="sr-only">Copy</span>
|
||||
</InputGroupButton>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<FieldDescription>
|
||||
Header positioned above the textarea.
|
||||
</FieldDescription>
|
||||
</Field>
|
||||
</FieldGroup>
|
||||
)
|
||||
}
|
||||
@@ -1,102 +1,18 @@
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuGroup,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/examples/base/ui/dropdown-menu"
|
||||
import {
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupButton,
|
||||
InputGroupInput,
|
||||
InputGroupText,
|
||||
InputGroupTextarea,
|
||||
} from "@/examples/base/ui/input-group"
|
||||
import { Separator } from "@/examples/base/ui/separator"
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from "@/examples/base/ui/tooltip"
|
||||
import { IconCheck, IconInfoCircle, IconPlus } from "@tabler/icons-react"
|
||||
import { ArrowUpIcon, Search } from "lucide-react"
|
||||
import { Search } from "lucide-react"
|
||||
|
||||
export default function InputGroupDemo() {
|
||||
export function InputGroupDemo() {
|
||||
return (
|
||||
<div className="grid w-full max-w-sm gap-6">
|
||||
<InputGroup>
|
||||
<InputGroupInput placeholder="Search..." />
|
||||
<InputGroupAddon>
|
||||
<Search />
|
||||
</InputGroupAddon>
|
||||
<InputGroupAddon align="inline-end">12 results</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<InputGroup>
|
||||
<InputGroupInput placeholder="example.com" className="!pl-1" />
|
||||
<InputGroupAddon>
|
||||
<InputGroupText>https://</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<Tooltip>
|
||||
<TooltipTrigger
|
||||
render={
|
||||
<InputGroupButton className="rounded-full" size="icon-xs" />
|
||||
}
|
||||
>
|
||||
<IconInfoCircle />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>This is content in a tooltip.</TooltipContent>
|
||||
</Tooltip>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<InputGroup>
|
||||
<InputGroupTextarea placeholder="Ask, Search or Chat..." />
|
||||
<InputGroupAddon align="block-end">
|
||||
<InputGroupButton
|
||||
variant="outline"
|
||||
className="rounded-full"
|
||||
size="icon-xs"
|
||||
>
|
||||
<IconPlus />
|
||||
</InputGroupButton>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger render={<InputGroupButton variant="ghost" />}>
|
||||
Auto
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent
|
||||
side="top"
|
||||
align="start"
|
||||
className="[--radius:0.95rem]"
|
||||
>
|
||||
<DropdownMenuGroup>
|
||||
<DropdownMenuItem>Auto</DropdownMenuItem>
|
||||
<DropdownMenuItem>Agent</DropdownMenuItem>
|
||||
<DropdownMenuItem>Manual</DropdownMenuItem>
|
||||
</DropdownMenuGroup>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<InputGroupText className="ml-auto">52% used</InputGroupText>
|
||||
<Separator orientation="vertical" className="!h-4" />
|
||||
<InputGroupButton
|
||||
variant="default"
|
||||
className="rounded-full"
|
||||
size="icon-xs"
|
||||
disabled
|
||||
>
|
||||
<ArrowUpIcon />
|
||||
<span className="sr-only">Send</span>
|
||||
</InputGroupButton>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<InputGroup>
|
||||
<InputGroupInput placeholder="@shadcn" />
|
||||
<InputGroupAddon align="inline-end">
|
||||
<div className="bg-primary text-primary-foreground flex size-4 items-center justify-center rounded-full">
|
||||
<IconCheck className="size-3" />
|
||||
</div>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</div>
|
||||
<InputGroup className="max-w-xs">
|
||||
<InputGroupInput placeholder="Search..." />
|
||||
<InputGroupAddon>
|
||||
<Search />
|
||||
</InputGroupAddon>
|
||||
<InputGroupAddon align="inline-end">12 results</InputGroupAddon>
|
||||
</InputGroup>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use client"
|
||||
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
@@ -13,7 +15,7 @@ import {
|
||||
} from "@/examples/base/ui/input-group"
|
||||
import { ChevronDownIcon, MoreHorizontal } from "lucide-react"
|
||||
|
||||
export default function InputGroupDropdown() {
|
||||
export function InputGroupDropdown() {
|
||||
return (
|
||||
<div className="grid w-full max-w-sm gap-4">
|
||||
<InputGroup>
|
||||
@@ -31,7 +33,7 @@ export default function InputGroupDropdown() {
|
||||
>
|
||||
<MoreHorizontal />
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuContent align="end" sideOffset={8} alignOffset={-4}>
|
||||
<DropdownMenuGroup>
|
||||
<DropdownMenuItem>Settings</DropdownMenuItem>
|
||||
<DropdownMenuItem>Copy path</DropdownMenuItem>
|
||||
@@ -41,7 +43,7 @@ export default function InputGroupDropdown() {
|
||||
</DropdownMenu>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<InputGroup className="[--radius:1rem]">
|
||||
<InputGroup>
|
||||
<InputGroupInput placeholder="Enter search query" />
|
||||
<InputGroupAddon align="inline-end">
|
||||
<DropdownMenu>
|
||||
@@ -52,7 +54,7 @@ export default function InputGroupDropdown() {
|
||||
>
|
||||
Search In... <ChevronDownIcon className="size-3" />
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" className="[--radius:0.95rem]">
|
||||
<DropdownMenuContent align="end" sideOffset={8} alignOffset={-4}>
|
||||
<DropdownMenuGroup>
|
||||
<DropdownMenuItem>Documentation</DropdownMenuItem>
|
||||
<DropdownMenuItem>Blog Posts</DropdownMenuItem>
|
||||
|
||||
26
apps/v4/examples/base/input-group-inline-end.tsx
Normal file
26
apps/v4/examples/base/input-group-inline-end.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import { Field, FieldDescription, FieldLabel } from "@/examples/base/ui/field"
|
||||
import {
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupInput,
|
||||
} from "@/examples/base/ui/input-group"
|
||||
import { EyeOffIcon } from "lucide-react"
|
||||
|
||||
export function InputGroupInlineEnd() {
|
||||
return (
|
||||
<Field className="max-w-sm">
|
||||
<FieldLabel htmlFor="inline-end-input">Input</FieldLabel>
|
||||
<InputGroup>
|
||||
<InputGroupInput
|
||||
id="inline-end-input"
|
||||
type="password"
|
||||
placeholder="Enter password"
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<EyeOffIcon />
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<FieldDescription>Icon positioned at the end.</FieldDescription>
|
||||
</Field>
|
||||
)
|
||||
}
|
||||
22
apps/v4/examples/base/input-group-inline-start.tsx
Normal file
22
apps/v4/examples/base/input-group-inline-start.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import { Field, FieldDescription, FieldLabel } from "@/examples/base/ui/field"
|
||||
import {
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupInput,
|
||||
} from "@/examples/base/ui/input-group"
|
||||
import { SearchIcon } from "lucide-react"
|
||||
|
||||
export function InputGroupInlineStart() {
|
||||
return (
|
||||
<Field className="max-w-sm">
|
||||
<FieldLabel htmlFor="inline-start-input">Input</FieldLabel>
|
||||
<InputGroup>
|
||||
<InputGroupInput id="inline-start-input" placeholder="Search..." />
|
||||
<InputGroupAddon align="inline-start">
|
||||
<SearchIcon className="text-muted-foreground" />
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<FieldDescription>Icon positioned at the start.</FieldDescription>
|
||||
</Field>
|
||||
)
|
||||
}
|
||||
21
apps/v4/examples/base/input-group-kbd.tsx
Normal file
21
apps/v4/examples/base/input-group-kbd.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import {
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupInput,
|
||||
} from "@/examples/base/ui/input-group"
|
||||
import { Kbd } from "@/examples/base/ui/kbd"
|
||||
import { SearchIcon } from "lucide-react"
|
||||
|
||||
export function InputGroupKbd() {
|
||||
return (
|
||||
<InputGroup className="max-w-sm">
|
||||
<InputGroupInput placeholder="Search..." />
|
||||
<InputGroupAddon>
|
||||
<SearchIcon className="text-muted-foreground" />
|
||||
</InputGroupAddon>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<Kbd>⌘K</Kbd>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
)
|
||||
}
|
||||
@@ -10,27 +10,27 @@ import { LoaderIcon } from "lucide-react"
|
||||
export default function InputGroupSpinner() {
|
||||
return (
|
||||
<div className="grid w-full max-w-sm gap-4">
|
||||
<InputGroup data-disabled>
|
||||
<InputGroupInput placeholder="Searching..." disabled />
|
||||
<InputGroup>
|
||||
<InputGroupInput placeholder="Searching..." />
|
||||
<InputGroupAddon align="inline-end">
|
||||
<Spinner />
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<InputGroup data-disabled>
|
||||
<InputGroupInput placeholder="Processing..." disabled />
|
||||
<InputGroup>
|
||||
<InputGroupInput placeholder="Processing..." />
|
||||
<InputGroupAddon>
|
||||
<Spinner />
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<InputGroup data-disabled>
|
||||
<InputGroupInput placeholder="Saving changes..." disabled />
|
||||
<InputGroup>
|
||||
<InputGroupInput placeholder="Saving changes..." />
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>Saving...</InputGroupText>
|
||||
<Spinner />
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<InputGroup data-disabled>
|
||||
<InputGroupInput placeholder="Refreshing data..." disabled />
|
||||
<InputGroup>
|
||||
<InputGroupInput placeholder="Refreshing data..." />
|
||||
<InputGroupAddon>
|
||||
<LoaderIcon className="animate-spin" />
|
||||
</InputGroupAddon>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
"use client"
|
||||
|
||||
import {
|
||||
Field,
|
||||
FieldDescription,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Button } from "@/examples/base/ui/button"
|
||||
"use client"
|
||||
|
||||
import { ButtonGroup, ButtonGroupText } from "@/examples/base/ui/button-group"
|
||||
import {
|
||||
DropdownMenu,
|
||||
@@ -12,7 +13,6 @@ import {
|
||||
FieldGroup,
|
||||
FieldLabel,
|
||||
} from "@/examples/base/ui/field"
|
||||
import { Input } from "@/examples/base/ui/input"
|
||||
import {
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
|
||||
49
apps/v4/examples/radix/input-group-block-end.tsx
Normal file
49
apps/v4/examples/radix/input-group-block-end.tsx
Normal file
@@ -0,0 +1,49 @@
|
||||
import {
|
||||
Field,
|
||||
FieldDescription,
|
||||
FieldGroup,
|
||||
FieldLabel,
|
||||
} from "@/examples/radix/ui/field"
|
||||
import {
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupButton,
|
||||
InputGroupInput,
|
||||
InputGroupText,
|
||||
InputGroupTextarea,
|
||||
} from "@/examples/radix/ui/input-group"
|
||||
|
||||
export function InputGroupBlockEnd() {
|
||||
return (
|
||||
<FieldGroup className="max-w-sm">
|
||||
<Field>
|
||||
<FieldLabel htmlFor="block-end-input">Input</FieldLabel>
|
||||
<InputGroup className="h-auto">
|
||||
<InputGroupInput id="block-end-input" placeholder="Enter amount" />
|
||||
<InputGroupAddon align="block-end">
|
||||
<InputGroupText>USD</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<FieldDescription>Footer positioned below the input.</FieldDescription>
|
||||
</Field>
|
||||
<Field>
|
||||
<FieldLabel htmlFor="block-end-textarea">Textarea</FieldLabel>
|
||||
<InputGroup>
|
||||
<InputGroupTextarea
|
||||
id="block-end-textarea"
|
||||
placeholder="Write a comment..."
|
||||
/>
|
||||
<InputGroupAddon align="block-end">
|
||||
<InputGroupText>0/280</InputGroupText>
|
||||
<InputGroupButton variant="default" size="sm" className="ml-auto">
|
||||
Post
|
||||
</InputGroupButton>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<FieldDescription>
|
||||
Footer positioned below the textarea.
|
||||
</FieldDescription>
|
||||
</Field>
|
||||
</FieldGroup>
|
||||
)
|
||||
}
|
||||
56
apps/v4/examples/radix/input-group-block-start.tsx
Normal file
56
apps/v4/examples/radix/input-group-block-start.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import {
|
||||
Field,
|
||||
FieldDescription,
|
||||
FieldGroup,
|
||||
FieldLabel,
|
||||
} from "@/examples/radix/ui/field"
|
||||
import {
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupButton,
|
||||
InputGroupInput,
|
||||
InputGroupText,
|
||||
InputGroupTextarea,
|
||||
} from "@/examples/radix/ui/input-group"
|
||||
import { CopyIcon, FileCodeIcon } from "lucide-react"
|
||||
|
||||
export function InputGroupBlockStart() {
|
||||
return (
|
||||
<FieldGroup className="max-w-sm">
|
||||
<Field>
|
||||
<FieldLabel htmlFor="block-start-input">Input</FieldLabel>
|
||||
<InputGroup className="h-auto">
|
||||
<InputGroupInput
|
||||
id="block-start-input"
|
||||
placeholder="Enter your name"
|
||||
/>
|
||||
<InputGroupAddon align="block-start">
|
||||
<InputGroupText>Full Name</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<FieldDescription>Header positioned above the input.</FieldDescription>
|
||||
</Field>
|
||||
<Field>
|
||||
<FieldLabel htmlFor="block-start-textarea">Textarea</FieldLabel>
|
||||
<InputGroup>
|
||||
<InputGroupTextarea
|
||||
id="block-start-textarea"
|
||||
placeholder="console.log('Hello, world!');"
|
||||
className="font-mono text-sm"
|
||||
/>
|
||||
<InputGroupAddon align="block-start">
|
||||
<FileCodeIcon className="text-muted-foreground" />
|
||||
<InputGroupText className="font-mono">script.js</InputGroupText>
|
||||
<InputGroupButton size="icon-xs" className="ml-auto">
|
||||
<CopyIcon />
|
||||
<span className="sr-only">Copy</span>
|
||||
</InputGroupButton>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<FieldDescription>
|
||||
Header positioned above the textarea.
|
||||
</FieldDescription>
|
||||
</Field>
|
||||
</FieldGroup>
|
||||
)
|
||||
}
|
||||
@@ -1,100 +1,18 @@
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuGroup,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/examples/radix/ui/dropdown-menu"
|
||||
import {
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupButton,
|
||||
InputGroupInput,
|
||||
InputGroupText,
|
||||
InputGroupTextarea,
|
||||
} from "@/examples/radix/ui/input-group"
|
||||
import { Separator } from "@/examples/radix/ui/separator"
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from "@/examples/radix/ui/tooltip"
|
||||
import { IconCheck, IconInfoCircle, IconPlus } from "@tabler/icons-react"
|
||||
import { ArrowUpIcon, Search } from "lucide-react"
|
||||
import { Search } from "lucide-react"
|
||||
|
||||
export default function InputGroupDemo() {
|
||||
export function InputGroupDemo() {
|
||||
return (
|
||||
<div className="grid w-full max-w-sm gap-6">
|
||||
<InputGroup>
|
||||
<InputGroupInput placeholder="Search..." />
|
||||
<InputGroupAddon>
|
||||
<Search />
|
||||
</InputGroupAddon>
|
||||
<InputGroupAddon align="inline-end">12 results</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<InputGroup>
|
||||
<InputGroupInput placeholder="example.com" className="!pl-1" />
|
||||
<InputGroupAddon>
|
||||
<InputGroupText>https://</InputGroupText>
|
||||
</InputGroupAddon>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<InputGroupButton className="rounded-full" size="icon-xs">
|
||||
<IconInfoCircle />
|
||||
</InputGroupButton>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>This is content in a tooltip.</TooltipContent>
|
||||
</Tooltip>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<InputGroup>
|
||||
<InputGroupTextarea placeholder="Ask, Search or Chat..." />
|
||||
<InputGroupAddon align="block-end">
|
||||
<InputGroupButton
|
||||
variant="outline"
|
||||
className="rounded-full"
|
||||
size="icon-xs"
|
||||
>
|
||||
<IconPlus />
|
||||
</InputGroupButton>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<InputGroupButton variant="ghost">Auto</InputGroupButton>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent
|
||||
side="top"
|
||||
align="start"
|
||||
className="[--radius:0.95rem]"
|
||||
>
|
||||
<DropdownMenuGroup>
|
||||
<DropdownMenuItem>Auto</DropdownMenuItem>
|
||||
<DropdownMenuItem>Agent</DropdownMenuItem>
|
||||
<DropdownMenuItem>Manual</DropdownMenuItem>
|
||||
</DropdownMenuGroup>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<InputGroupText className="ml-auto">52% used</InputGroupText>
|
||||
<Separator orientation="vertical" className="!h-4" />
|
||||
<InputGroupButton
|
||||
variant="default"
|
||||
className="rounded-full"
|
||||
size="icon-xs"
|
||||
disabled
|
||||
>
|
||||
<ArrowUpIcon />
|
||||
<span className="sr-only">Send</span>
|
||||
</InputGroupButton>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<InputGroup>
|
||||
<InputGroupInput placeholder="@shadcn" />
|
||||
<InputGroupAddon align="inline-end">
|
||||
<div className="bg-primary text-primary-foreground flex size-4 items-center justify-center rounded-full">
|
||||
<IconCheck className="size-3" />
|
||||
</div>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
</div>
|
||||
<InputGroup className="max-w-xs">
|
||||
<InputGroupInput placeholder="Search..." />
|
||||
<InputGroupAddon>
|
||||
<Search />
|
||||
</InputGroupAddon>
|
||||
<InputGroupAddon align="inline-end">12 results</InputGroupAddon>
|
||||
</InputGroup>
|
||||
)
|
||||
}
|
||||
|
||||
26
apps/v4/examples/radix/input-group-inline-end.tsx
Normal file
26
apps/v4/examples/radix/input-group-inline-end.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import { Field, FieldDescription, FieldLabel } from "@/examples/radix/ui/field"
|
||||
import {
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupInput,
|
||||
} from "@/examples/radix/ui/input-group"
|
||||
import { EyeOffIcon } from "lucide-react"
|
||||
|
||||
export function InputGroupInlineEnd() {
|
||||
return (
|
||||
<Field className="max-w-sm">
|
||||
<FieldLabel htmlFor="inline-end-input">Input</FieldLabel>
|
||||
<InputGroup>
|
||||
<InputGroupInput
|
||||
id="inline-end-input"
|
||||
type="password"
|
||||
placeholder="Enter password"
|
||||
/>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<EyeOffIcon />
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<FieldDescription>Icon positioned at the end.</FieldDescription>
|
||||
</Field>
|
||||
)
|
||||
}
|
||||
22
apps/v4/examples/radix/input-group-inline-start.tsx
Normal file
22
apps/v4/examples/radix/input-group-inline-start.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
import { Field, FieldDescription, FieldLabel } from "@/examples/radix/ui/field"
|
||||
import {
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupInput,
|
||||
} from "@/examples/radix/ui/input-group"
|
||||
import { SearchIcon } from "lucide-react"
|
||||
|
||||
export function InputGroupInlineStart() {
|
||||
return (
|
||||
<Field className="max-w-sm">
|
||||
<FieldLabel htmlFor="inline-start-input">Input</FieldLabel>
|
||||
<InputGroup>
|
||||
<InputGroupInput id="inline-start-input" placeholder="Search..." />
|
||||
<InputGroupAddon align="inline-start">
|
||||
<SearchIcon className="text-muted-foreground" />
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<FieldDescription>Icon positioned at the start.</FieldDescription>
|
||||
</Field>
|
||||
)
|
||||
}
|
||||
21
apps/v4/examples/radix/input-group-kbd.tsx
Normal file
21
apps/v4/examples/radix/input-group-kbd.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import {
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupInput,
|
||||
} from "@/examples/radix/ui/input-group"
|
||||
import { Kbd } from "@/examples/radix/ui/kbd"
|
||||
import { SearchIcon } from "lucide-react"
|
||||
|
||||
export function InputGroupKbd() {
|
||||
return (
|
||||
<InputGroup className="max-w-sm">
|
||||
<InputGroupInput placeholder="Search..." />
|
||||
<InputGroupAddon>
|
||||
<SearchIcon className="text-muted-foreground" />
|
||||
</InputGroupAddon>
|
||||
<InputGroupAddon align="inline-end">
|
||||
<Kbd>⌘K</Kbd>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
)
|
||||
}
|
||||
@@ -10,27 +10,27 @@ import { LoaderIcon } from "lucide-react"
|
||||
export default function InputGroupSpinner() {
|
||||
return (
|
||||
<div className="grid w-full max-w-sm gap-4">
|
||||
<InputGroup data-disabled>
|
||||
<InputGroupInput placeholder="Searching..." disabled />
|
||||
<InputGroup>
|
||||
<InputGroupInput placeholder="Searching..." />
|
||||
<InputGroupAddon align="inline-end">
|
||||
<Spinner />
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<InputGroup data-disabled>
|
||||
<InputGroupInput placeholder="Processing..." disabled />
|
||||
<InputGroup>
|
||||
<InputGroupInput placeholder="Processing..." />
|
||||
<InputGroupAddon>
|
||||
<Spinner />
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<InputGroup data-disabled>
|
||||
<InputGroupInput placeholder="Saving changes..." disabled />
|
||||
<InputGroup>
|
||||
<InputGroupInput placeholder="Saving changes..." />
|
||||
<InputGroupAddon align="inline-end">
|
||||
<InputGroupText>Saving...</InputGroupText>
|
||||
<Spinner />
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
<InputGroup data-disabled>
|
||||
<InputGroupInput placeholder="Refreshing data..." disabled />
|
||||
<InputGroup>
|
||||
<InputGroupInput placeholder="Refreshing data..." />
|
||||
<InputGroupAddon>
|
||||
<LoaderIcon className="animate-spin" />
|
||||
</InputGroupAddon>
|
||||
|
||||
Reference in New Issue
Block a user