InputGroup
Compose multiple Input / Button / Select / static labels into one unit with shared outer radius and border.
Basic usage
InputGroup is a pure styling wrapper. Put form controls inside in order; adjacent inner radii are removed automatically and the first / last element inherits the outer radius. Static labels are rendered with <span class="cf-input-group__addon">.
背景 视口
@
<script setup lang="ts">
import { ref } from 'vue';
import { CfInputGroup, CfInput } from '@chufix-design/vue';
const search = ref('');
</script>
<template>
<CfInputGroup>
<span class="cf-input-group__addon">@</span>
<CfInput v-model="search" placeholder="username" />
</CfInputGroup>
</template> <script setup>
import { ref } from 'vue';
import { CfInputGroup, CfInput } from '@chufix-design/vue';
const search = ref('');
</script>
<template>
<CfInputGroup>
<span class="cf-input-group__addon">@</span>
<CfInput v-model="search" placeholder="username" />
</CfInputGroup>
</template> import { useState } from 'react';
import { CfInput, CfInputGroup } from '@chufix-design/react';
export default function Demo() {
const [search, setSearch] = useState('');
return (
<>
<CfInputGroup>
<span className="cf-input-group__addon">@</span>
<CfInput value={search} onChange={setSearch} placeholder="username" />
</CfInputGroup>
</>
);
} import { useState } from 'react';
import { CfInput, CfInputGroup } from '@chufix-design/react';
export default function Demo() {
const [search, setSearch] = useState('');
return (
<>
<CfInputGroup>
<span className="cf-input-group__addon">@</span>
<CfInput value={search} onChange={setSearch} placeholder="username" />
</CfInputGroup>
</>
);
} With Select / Button
The most common combination — “URL input + protocol select + submit button” — three segments share a single border.
背景 视口
<script setup lang="ts">
import { ref } from 'vue';
import { CfInputGroup, CfInput, CfButton, CfSelect } from '@chufix-design/vue';
const protocol = ref('https');
const host = ref('chufix.com');
const protocols = [
{ label: 'https://', value: 'https' },
{ label: 'http://', value: 'http' },
];
</script>
<template>
<CfInputGroup>
<CfSelect v-model="protocol" :options="protocols" />
<CfInput v-model="host" placeholder="example.com" />
<CfButton>访问</CfButton>
</CfInputGroup>
</template> <script setup>
import { ref } from 'vue';
import { CfInputGroup, CfInput, CfButton, CfSelect } from '@chufix-design/vue';
const protocol = ref('https');
const host = ref('chufix.com');
const protocols = [
{ label: 'https://', value: 'https' },
{ label: 'http://', value: 'http' },
];
</script>
<template>
<CfInputGroup>
<CfSelect v-model="protocol" :options="protocols" />
<CfInput v-model="host" placeholder="example.com" />
<CfButton>访问</CfButton>
</CfInputGroup>
</template> import { useState } from 'react';
import { CfButton, CfInput, CfInputGroup, CfSelect } from '@chufix-design/react';
export default function Demo() {
const [protocol, setProtocol] = useState('https');
const [host, setHost] = useState('chufix.com');
const protocols = [
{ label: 'https://', value: 'https' },
{ label: 'http://', value: 'http' },
];
return (
<>
<CfInputGroup>
<CfSelect value={protocol} onChange={setProtocol} options={protocols} />
<CfInput value={host} onChange={setHost} placeholder="example.com" />
<CfButton>访问</CfButton>
</CfInputGroup>
</>
);
} import { useState } from 'react';
import { CfButton, CfInput, CfInputGroup, CfSelect } from '@chufix-design/react';
export default function Demo() {
const [protocol, setProtocol] = useState('https');
const [host, setHost] = useState('chufix.com');
const protocols = [
{ label: 'https://', value: 'https' },
{ label: 'http://', value: 'http' },
];
return (
<>
<CfInputGroup>
<CfSelect value={protocol} onChange={setProtocol} options={protocols} />
<CfInput value={host} onChange={setHost} placeholder="example.com" />
<CfButton>访问</CfButton>
</CfInputGroup>
</>
);
} Leading and trailing addons
<span class="cf-input-group__addon"> can sit on either side of the input — common for currency or URL path prefixes/suffixes.
背景 视口
¥RMB
https:///path
<script setup lang="ts">
import { ref } from 'vue';
import { CfInputGroup, CfInput } from '@chufix-design/vue';
const price = ref('');
const url = ref('');
</script>
<template>
<div class="demo-stack">
<CfInputGroup>
<span class="cf-input-group__addon">¥</span>
<CfInput v-model="price" placeholder="价格" />
<span class="cf-input-group__addon">RMB</span>
</CfInputGroup>
<CfInputGroup>
<span class="cf-input-group__addon">https://</span>
<CfInput v-model="url" placeholder="example.com" />
<span class="cf-input-group__addon">/path</span>
</CfInputGroup>
</div>
</template> <script setup>
import { ref } from 'vue';
import { CfInputGroup, CfInput } from '@chufix-design/vue';
const price = ref('');
const url = ref('');
</script>
<template>
<div class="demo-stack">
<CfInputGroup>
<span class="cf-input-group__addon">¥</span>
<CfInput v-model="price" placeholder="价格" />
<span class="cf-input-group__addon">RMB</span>
</CfInputGroup>
<CfInputGroup>
<span class="cf-input-group__addon">https://</span>
<CfInput v-model="url" placeholder="example.com" />
<span class="cf-input-group__addon">/path</span>
</CfInputGroup>
</div>
</template> import { useState } from 'react';
import { CfInput, CfInputGroup } from '@chufix-design/react';
export default function Demo() {
const [price, setPrice] = useState('');
const [url, setUrl] = useState('');
return (
<>
<div className="demo-stack">
<CfInputGroup>
<span className="cf-input-group__addon">¥</span>
<CfInput value={price} onChange={setPrice} placeholder="价格" />
<span className="cf-input-group__addon">RMB</span>
</CfInputGroup>
<CfInputGroup>
<span className="cf-input-group__addon">https://</span>
<CfInput value={url} onChange={setUrl} placeholder="example.com" />
<span className="cf-input-group__addon">/path</span>
</CfInputGroup>
</div>
</>
);
} import { useState } from 'react';
import { CfInput, CfInputGroup } from '@chufix-design/react';
export default function Demo() {
const [price, setPrice] = useState('');
const [url, setUrl] = useState('');
return (
<>
<div className="demo-stack">
<CfInputGroup>
<span className="cf-input-group__addon">¥</span>
<CfInput value={price} onChange={setPrice} placeholder="价格" />
<span className="cf-input-group__addon">RMB</span>
</CfInputGroup>
<CfInputGroup>
<span className="cf-input-group__addon">https://</span>
<CfInput value={url} onChange={setUrl} placeholder="example.com" />
<span className="cf-input-group__addon">/path</span>
</CfInputGroup>
</div>
</>
);
} Equal-width stretch
stretch makes children share the parent width equally — handy for a full-row search box + submit button.
背景 视口
<script setup lang="ts">
import { ref } from 'vue';
import { CfInputGroup, CfInput, CfButton } from '@chufix-design/vue';
const q = ref('');
</script>
<template>
<div style="max-width: 24rem;">
<CfInputGroup stretch>
<CfInput v-model="q" placeholder="搜索…" />
<CfButton variant="primary">搜索</CfButton>
</CfInputGroup>
</div>
</template> <script setup>
import { ref } from 'vue';
import { CfInputGroup, CfInput, CfButton } from '@chufix-design/vue';
const q = ref('');
</script>
<template>
<div style="max-width: 24rem;">
<CfInputGroup stretch>
<CfInput v-model="q" placeholder="搜索…" />
<CfButton variant="primary">搜索</CfButton>
</CfInputGroup>
</div>
</template> import { useState } from 'react';
import { CfButton, CfInput, CfInputGroup } from '@chufix-design/react';
export default function Demo() {
const [q, setQ] = useState('');
return (
<>
<div style={{ maxWidth: "24rem" }}>
<CfInputGroup stretch>
<CfInput value={q} onChange={setQ} placeholder="搜索…" />
<CfButton variant="primary">搜索</CfButton>
</CfInputGroup>
</div>
</>
);
} import { useState } from 'react';
import { CfButton, CfInput, CfInputGroup } from '@chufix-design/react';
export default function Demo() {
const [q, setQ] = useState('');
return (
<>
<div style={{ maxWidth: "24rem" }}>
<CfInputGroup stretch>
<CfInput value={q} onChange={setQ} placeholder="搜索…" />
<CfButton variant="primary">搜索</CfButton>
</CfInputGroup>
</div>
</>
);
} API · Props
| Prop | Type | Default | Description |
|---|---|---|---|
orientation | 'horizontal' | 'vertical' | 'horizontal' | Layout direction |
size | 'sm' | 'md' | 'lg' | 'md' | Size of static addons (controls keep their own size) |
stretch | boolean | false | Children fill parent equally |
反馈与讨论
InputGroup · Discussion