Variable-aware input
Enhanced Input that auto-detects `{{var}}` template variables and highlights them; unknown variables get a red squiggle.
Basic usage
Implementation: a native input with transparent text underneath, plus an overlay of the same size rendering the highlighted text. Cursor positions stay perfectly aligned.
Names listed in variables are treated as “known” and highlighted with accent; others are “unknown” and get a red squiggle.
背景 视口
已知变量:base_url · user_id · auth_token
<script setup lang="ts">
import { ref } from 'vue';
import { CfVariableAwareInput } from '@chufix-design/vue';
const value = ref('{{base_url}}/users/{{user_id}}/orders?token={{auth_token}}');
const known = ['base_url', 'user_id', 'auth_token'];
</script>
<template>
<div style="width: 100%; max-width: 920px;">
<CfVariableAwareInput v-model="value" :variables="known" placeholder="试试输入 {{base_url}}…" />
<div style="margin-top: 8px; font-size: 12px; color: var(--fg-3);">
已知变量:{{ known.join(' · ') }}
</div>
</div>
</template> <script setup>
import { ref } from 'vue';
import { CfVariableAwareInput } from '@chufix-design/vue';
const value = ref('{{base_url}}/users/{{user_id}}/orders?token={{auth_token}}');
const known = ['base_url', 'user_id', 'auth_token'];
</script>
<template>
<div style="width: 100%; max-width: 920px;">
<CfVariableAwareInput v-model="value" :variables="known" placeholder="试试输入 {{base_url}}…" />
<div style="margin-top: 8px; font-size: 12px; color: var(--fg-3);">
已知变量:{{ known.join(' · ') }}
</div>
</div>
</template> import { useState } from 'react';
import { CfVariableAwareInput } from '@chufix-design/react';
export default function Demo() {
const [value, setValue] = useState('{{base_url}}/users/{{user_id}}/orders?token={{auth_token}}');
const known = ['base_url', 'user_id', 'auth_token'];
return (
<>
<div style={{ width: "100%", maxWidth: 920 }}>
<CfVariableAwareInput value={value} onChange={setValue} variables={known} placeholder="试试输入 {{base_url}}…" />
<div style={{ marginTop: 8, fontSize: 12, color: "var(--fg-3)" }}>
已知变量:{known.join(' · ')}
</div>
</div>
</>
);
} import { useState } from 'react';
import { CfVariableAwareInput } from '@chufix-design/react';
export default function Demo() {
const [value, setValue] = useState('{{base_url}}/users/{{user_id}}/orders?token={{auth_token}}');
const known = ['base_url', 'user_id', 'auth_token'];
return (
<>
<div style={{ width: "100%", maxWidth: 920 }}>
<CfVariableAwareInput value={value} onChange={setValue} variables={known} placeholder="试试输入 {{base_url}}…" />
<div style={{ marginTop: 8, fontSize: 12, color: "var(--fg-3)" }}>
已知变量:{known.join(' · ')}
</div>
</div>
</>
);
} Variable interactions
variables can be either a string list or an object list. Typing {{ opens suggestions, and clicking a recognized variable opens details. The component only emits variable-update / variable-create; persistence stays in user code.
背景 视口
输入 {{ 触发候选;点击变量查看详情。
<script setup lang="ts">
import { ref } from 'vue';
import { CfVariableAwareInput } from '@chufix-design/vue';
const value = ref('请求 {{base_url}}/v2/users/{{user_id}}?token={{token}}');
const lastAction = ref('输入 {{ 触发候选;点击变量查看详情。');
const variables = [
{
name: 'base_url',
label: 'Base URL',
value: 'https://api.chufix.dev',
description: '项目级 API 根地址,可在弹层中修改。',
scope: 'project',
editable: true,
},
{
name: 'user_id',
label: 'User ID',
value: 'u_1024',
description: '当前登录用户 ID。',
scope: 'local',
},
{
name: 'token',
label: 'Auth Token',
value: 'cf_live_xxx',
description: '授权令牌,由外层业务控制保存。',
scope: 'global',
editable: true,
},
];
</script>
<template>
<div style="width: 100%; max-width: 920px;">
<CfVariableAwareInput
v-model="value"
:variables="variables"
placeholder="输入 {{ 触发变量选择"
@variable-select="(variable) => lastAction = `插入变量:${variable.name}`"
@variable-update="(payload) => lastAction = `请求更新 ${payload.name} = ${payload.value}`"
@variable-create="(payload) => lastAction = `请求创建变量:${payload.name}`"
/>
<div style="margin-top: 10px; color: var(--fg-3); font-size: 12px;">
{{ lastAction }}
</div>
</div>
</template> <script setup>
import { ref } from 'vue';
import { CfVariableAwareInput } from '@chufix-design/vue';
const value = ref('请求 {{base_url}}/v2/users/{{user_id}}?token={{token}}');
const lastAction = ref('输入 {{ 触发候选;点击变量查看详情。');
const variables = [
{
name: 'base_url',
label: 'Base URL',
value: 'https://api.chufix.dev',
description: '项目级 API 根地址,可在弹层中修改。',
scope: 'project',
editable: true,
},
{
name: 'user_id',
label: 'User ID',
value: 'u_1024',
description: '当前登录用户 ID。',
scope: 'local',
},
{
name: 'token',
label: 'Auth Token',
value: 'cf_live_xxx',
description: '授权令牌,由外层业务控制保存。',
scope: 'global',
editable: true,
},
];
</script>
<template>
<div style="width: 100%; max-width: 920px;">
<CfVariableAwareInput
v-model="value"
:variables="variables"
placeholder="输入 {{ 触发变量选择"
@variable-select="(variable) => lastAction = `插入变量:${variable.name}`"
@variable-update="(payload) => lastAction = `请求更新 ${payload.name} = ${payload.value}`"
@variable-create="(payload) => lastAction = `请求创建变量:${payload.name}`"
/>
<div style="margin-top: 10px; color: var(--fg-3); font-size: 12px;">
{{ lastAction }}
</div>
</div>
</template> import { useState } from 'react';
import { CfVariableAwareInput } from '@chufix-design/react';
export default function Demo() {
const [value, setValue] = useState('请求 {{base_url}}/v2/users/{{user_id}}?token={{token}}');
const [lastAction, setLastAction] = useState('输入 {{ 触发候选;点击变量查看详情。');
const variables = [
{
name: 'base_url',
label: 'Base URL',
value: 'https://api.chufix.dev',
description: '项目级 API 根地址,可在弹层中修改。',
scope: 'project',
editable: true,
},
{
name: 'user_id',
label: 'User ID',
value: 'u_1024',
description: '当前登录用户 ID。',
scope: 'local',
},
{
name: 'token',
label: 'Auth Token',
value: 'cf_live_xxx',
description: '授权令牌,由外层业务控制保存。',
scope: 'global',
editable: true,
},
];
return (
<>
<div style={{ width: "100%", maxWidth: 920 }}>
<CfVariableAwareInput value={value} onChange={setValue} variables={variables} placeholder="输入 {{ 触发变量选择" onVariableSelect={(variable) => setLastAction(`插入变量:${variable.name}`)}
onVariableUpdate={(payload) => setLastAction(`请求更新 ${payload.name} = ${payload.value}`)}
onVariableCreate={(payload) => setLastAction(`请求创建变量:${payload.name}`)}
/>
<div style={{ marginTop: 10, color: "var(--fg-3)", fontSize: 12 }}>
{lastAction}
</div>
</div>
</>
);
} import { useState } from 'react';
import { CfVariableAwareInput } from '@chufix-design/react';
export default function Demo() {
const [value, setValue] = useState('请求 {{base_url}}/v2/users/{{user_id}}?token={{token}}');
const [lastAction, setLastAction] = useState('输入 {{ 触发候选;点击变量查看详情。');
const variables = [
{
name: 'base_url',
label: 'Base URL',
value: 'https://api.chufix.dev',
description: '项目级 API 根地址,可在弹层中修改。',
scope: 'project',
editable: true,
},
{
name: 'user_id',
label: 'User ID',
value: 'u_1024',
description: '当前登录用户 ID。',
scope: 'local',
},
{
name: 'token',
label: 'Auth Token',
value: 'cf_live_xxx',
description: '授权令牌,由外层业务控制保存。',
scope: 'global',
editable: true,
},
];
return (
<>
<div style={{ width: "100%", maxWidth: 920 }}>
<CfVariableAwareInput value={value} onChange={setValue} variables={variables} placeholder="输入 {{ 触发变量选择" onVariableSelect={(variable) => setLastAction(`插入变量:${variable.name}`)}
onVariableUpdate={(payload) => setLastAction(`请求更新 ${payload.name} = ${payload.value}`)}
onVariableCreate={(payload) => setLastAction(`请求创建变量:${payload.name}`)}
/>
<div style={{ marginTop: 10, color: "var(--fg-3)", fontSize: 12 }}>
{lastAction}
</div>
</div>
</>
);
} Mixed state
A demo combining known (accent highlight) and unknown (red squiggle) variables.
背景 视口
<script setup lang="ts">
import { ref } from 'vue';
import { CfVariableAwareInput } from '@chufix-design/vue';
const v1 = ref('valid only: {{base_url}} / {{user_id}}');
const v2 = ref('mixed: {{base_url}}/v1/{{token}}/users/{{user_id}}');
const v3 = ref('all unknown: {{a}} {{b}} {{c}}');
const known = ['base_url', 'user_id'];
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 12px; width: 100%; max-width: 920px;">
<CfVariableAwareInput v-model="v1" :variables="known" />
<CfVariableAwareInput v-model="v2" :variables="known" />
<CfVariableAwareInput v-model="v3" :variables="known" />
</div>
</template> <script setup>
import { ref } from 'vue';
import { CfVariableAwareInput } from '@chufix-design/vue';
const v1 = ref('valid only: {{base_url}} / {{user_id}}');
const v2 = ref('mixed: {{base_url}}/v1/{{token}}/users/{{user_id}}');
const v3 = ref('all unknown: {{a}} {{b}} {{c}}');
const known = ['base_url', 'user_id'];
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 12px; width: 100%; max-width: 920px;">
<CfVariableAwareInput v-model="v1" :variables="known" />
<CfVariableAwareInput v-model="v2" :variables="known" />
<CfVariableAwareInput v-model="v3" :variables="known" />
</div>
</template> import { useState } from 'react';
import { CfVariableAwareInput } from '@chufix-design/react';
export default function Demo() {
const [v1, setV1] = useState('valid only: {{base_url}} / {{user_id}}');
const [v2, setV2] = useState('mixed: {{base_url}}/v1/{{token}}/users/{{user_id}}');
const [v3, setV3] = useState('all unknown: {{a}} {{b}} {{c}}');
const known = ['base_url', 'user_id'];
return (
<>
<div style={{ display: "flex", flexDirection: "column", gap: 12, width: "100%", maxWidth: 920 }}>
<CfVariableAwareInput value={v1} onChange={setV1} variables={known} />
<CfVariableAwareInput value={v2} onChange={setV2} variables={known} />
<CfVariableAwareInput value={v3} onChange={setV3} variables={known} />
</div>
</>
);
} import { useState } from 'react';
import { CfVariableAwareInput } from '@chufix-design/react';
export default function Demo() {
const [v1, setV1] = useState('valid only: {{base_url}} / {{user_id}}');
const [v2, setV2] = useState('mixed: {{base_url}}/v1/{{token}}/users/{{user_id}}');
const [v3, setV3] = useState('all unknown: {{a}} {{b}} {{c}}');
const known = ['base_url', 'user_id'];
return (
<>
<div style={{ display: "flex", flexDirection: "column", gap: 12, width: "100%", maxWidth: 920 }}>
<CfVariableAwareInput value={v1} onChange={setV1} variables={known} />
<CfVariableAwareInput value={v2} onChange={setV2} variables={known} />
<CfVariableAwareInput value={v3} onChange={setV3} variables={known} />
</div>
</>
);
} API
| Prop | Type | Default | Description |
|---|---|---|---|
modelValue / value | string | '' | Input value |
variables | (string | VariableOption)[] | [] | Known variable names or variable objects |
size | 'sm' | 'md' | 'lg' | 'md' | |
variant | 'outline' | 'filled' | 'outline' | |
suggest | boolean | true | Show suggestions when typing {{ |
suggestTrigger | string | '{{' | Suggestion trigger text |
interactive | boolean | true | Allow clicking variables to open the interaction popover |
showVariablePopover | boolean | true | Use the built-in variable detail popover |
placeholder / disabled / error |
| Event / extension | Description |
|---|---|
variable-select / onVariableSelect | Fired when a suggestion is inserted |
variable-click / onVariableClick | Fired when a recognized variable is clicked |
variable-update / onVariableUpdate | Fired by the built-in update action; the component does not persist data |
variable-create / onVariableCreate | Fired by the create action for an unknown variable |
Vue #option / React renderVariableOption | Custom suggestion option rendering |
Vue #variable-popover / React renderVariablePopover | Custom variable detail popover rendering |
反馈与讨论
Variable-aware input · Discussion