fix: migrate select to Base UI items API (#4655)

This commit is contained in:
yyhhyyyyyy
2026-05-06 21:38:58 +08:00
committed by GitHub
parent 38a3314b9b
commit d98f0e8ac3
38 changed files with 1187 additions and 485 deletions
@@ -24,6 +24,7 @@ import { Input } from '@/components/ui/input'
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
@@ -224,18 +225,26 @@ export function ChannelSelectorDialog({
return (
<div className='flex items-center gap-2'>
<Select
items={[
...ENDPOINT_OPTIONS.map((option) => ({
value: option.value,
label: option.label,
})),
]}
value={endpointType}
onValueChange={(v) => v !== null && handleTypeChange(v)}
>
<SelectTrigger className='h-8 w-32'>
<SelectValue />
</SelectTrigger>
<SelectContent>
{ENDPOINT_OPTIONS.map((option) => (
<SelectItem key={option.value} value={option.value}>
{option.label}
</SelectItem>
))}
<SelectContent alignItemWithTrigger={false}>
<SelectGroup>
{ENDPOINT_OPTIONS.map((option) => (
<SelectItem key={option.value} value={option.value}>
{option.label}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
{endpointType === 'custom' && (
@@ -18,6 +18,7 @@ import { Input } from '@/components/ui/input'
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
@@ -176,6 +177,38 @@ function GroupSection(props: GroupSectionProps) {
{props.items.map((rule) => (
<div key={rule._id} className='flex items-center gap-2'>
<Select
items={[
{
value: OP_ADD,
label: (
<StatusBadge
label={t(OP_BADGE_MAP[OP_ADD].label)}
variant={OP_BADGE_MAP[OP_ADD].variant}
copyable={false}
/>
),
},
{
value: OP_REMOVE,
label: (
<StatusBadge
label={t(OP_BADGE_MAP[OP_REMOVE].label)}
variant={OP_BADGE_MAP[OP_REMOVE].variant}
copyable={false}
/>
),
},
{
value: OP_APPEND,
label: (
<StatusBadge
label={t(OP_BADGE_MAP[OP_APPEND].label)}
variant={OP_BADGE_MAP[OP_APPEND].variant}
copyable={false}
/>
),
},
]}
value={rule.op}
onValueChange={(v) =>
v !== null && props.onUpdate(rule._id, 'op', v)
@@ -190,28 +223,30 @@ function GroupSection(props: GroupSectionProps) {
/>
</SelectValue>
</SelectTrigger>
<SelectContent>
<SelectItem value={OP_ADD}>
<StatusBadge
label={t(OP_BADGE_MAP[OP_ADD].label)}
variant={OP_BADGE_MAP[OP_ADD].variant}
copyable={false}
/>
</SelectItem>
<SelectItem value={OP_REMOVE}>
<StatusBadge
label={t(OP_BADGE_MAP[OP_REMOVE].label)}
variant={OP_BADGE_MAP[OP_REMOVE].variant}
copyable={false}
/>
</SelectItem>
<SelectItem value={OP_APPEND}>
<StatusBadge
label={t(OP_BADGE_MAP[OP_APPEND].label)}
variant={OP_BADGE_MAP[OP_APPEND].variant}
copyable={false}
/>
</SelectItem>
<SelectContent alignItemWithTrigger={false}>
<SelectGroup>
<SelectItem value={OP_ADD}>
<StatusBadge
label={t(OP_BADGE_MAP[OP_ADD].label)}
variant={OP_BADGE_MAP[OP_ADD].variant}
copyable={false}
/>
</SelectItem>
<SelectItem value={OP_REMOVE}>
<StatusBadge
label={t(OP_BADGE_MAP[OP_REMOVE].label)}
variant={OP_BADGE_MAP[OP_REMOVE].variant}
copyable={false}
/>
</SelectItem>
<SelectItem value={OP_APPEND}>
<StatusBadge
label={t(OP_BADGE_MAP[OP_APPEND].label)}
variant={OP_BADGE_MAP[OP_APPEND].variant}
copyable={false}
/>
</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
<Input
@@ -27,6 +27,7 @@ import { Label } from '@/components/ui/label'
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
@@ -415,6 +416,12 @@ function ConditionRow({ condition, onChange, onRemove }: ConditionRowProps) {
return (
<div className='flex items-center gap-2'>
<Select
items={[
...CONDITION_INPUT_OPTIONS.map((option) => ({
value: option.value,
label: t(option.labelKey),
})),
]}
value={condition.var}
onValueChange={(value) =>
onChange({ ...condition, var: value as TierConditionInput['var'] })
@@ -427,15 +434,18 @@ function ConditionRow({ condition, onChange, onRemove }: ConditionRowProps) {
: condition.var}
</SelectValue>
</SelectTrigger>
<SelectContent>
{CONDITION_INPUT_OPTIONS.map((option) => (
<SelectItem key={option.value} value={option.value}>
{t(option.labelKey)}
</SelectItem>
))}
<SelectContent alignItemWithTrigger={false}>
<SelectGroup>
{CONDITION_INPUT_OPTIONS.map((option) => (
<SelectItem key={option.value} value={option.value}>
{t(option.labelKey)}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
<Select
items={[...OPS.map((op) => ({ value: op, label: op }))]}
value={condition.op}
onValueChange={(value) =>
onChange({ ...condition, op: value as TierConditionInput['op'] })
@@ -444,12 +454,14 @@ function ConditionRow({ condition, onChange, onRemove }: ConditionRowProps) {
<SelectTrigger className='w-20' size='sm'>
<SelectValue />
</SelectTrigger>
<SelectContent>
{OPS.map((op) => (
<SelectItem key={op} value={op}>
{op}
</SelectItem>
))}
<SelectContent alignItemWithTrigger={false}>
<SelectGroup>
{OPS.map((op) => (
<SelectItem key={op} value={op}>
{op}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
<DraftNumberInput
@@ -960,6 +972,12 @@ function RuleConditionRow({
const renderTimeCondition = (timeCond: TimeCondition) => (
<>
<Select
items={[
...TIME_FUNCS.map((fn) => ({
value: fn,
label: getTimeFuncLabel(fn),
})),
]}
value={timeCond.timeFunc}
onValueChange={(value) =>
onChange({ ...timeCond, timeFunc: value as TimeFunc })
@@ -968,15 +986,23 @@ function RuleConditionRow({
<SelectTrigger className='w-32' size='sm'>
<SelectValue>{getTimeFuncLabel(timeCond.timeFunc)}</SelectValue>
</SelectTrigger>
<SelectContent>
{TIME_FUNCS.map((fn) => (
<SelectItem key={fn} value={fn}>
{getTimeFuncLabel(fn)}
</SelectItem>
))}
<SelectContent alignItemWithTrigger={false}>
<SelectGroup>
{TIME_FUNCS.map((fn) => (
<SelectItem key={fn} value={fn}>
{getTimeFuncLabel(fn)}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
<Select
items={[
...COMMON_TIMEZONES.map((tz) => ({
value: tz.value,
label: tz.label,
})),
]}
value={timeCond.timezone}
onValueChange={(value) =>
value !== null && onChange({ ...timeCond, timezone: value })
@@ -988,27 +1014,37 @@ function RuleConditionRow({
?.label ?? timeCond.timezone}
</SelectValue>
</SelectTrigger>
<SelectContent>
{COMMON_TIMEZONES.map((tz) => (
<SelectItem key={tz.value} value={tz.value}>
{tz.label}
</SelectItem>
))}
<SelectContent alignItemWithTrigger={false}>
<SelectGroup>
{COMMON_TIMEZONES.map((tz) => (
<SelectItem key={tz.value} value={tz.value}>
{tz.label}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
<Select
items={[
...matchOptions.map((option) => ({
value: option.value,
label: getMatchLabel(option.value),
})),
]}
value={timeCond.mode}
onValueChange={(v) => v !== null && handleModeChange(v)}
>
<SelectTrigger className='w-32' size='sm'>
<SelectValue>{getMatchLabel(timeCond.mode)}</SelectValue>
</SelectTrigger>
<SelectContent>
{matchOptions.map((option) => (
<SelectItem key={option.value} value={option.value}>
{getMatchLabel(option.value)}
</SelectItem>
))}
<SelectContent alignItemWithTrigger={false}>
<SelectGroup>
{matchOptions.map((option) => (
<SelectItem key={option.value} value={option.value}>
{getMatchLabel(option.value)}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
{timeCond.mode === MATCH_RANGE ? (
@@ -1055,18 +1091,26 @@ function RuleConditionRow({
className='w-44'
/>
<Select
items={[
...matchOptions.map((option) => ({
value: option.value,
label: getMatchLabel(option.value),
})),
]}
value={phCond.mode}
onValueChange={(v) => v !== null && handleModeChange(v)}
>
<SelectTrigger className='w-32' size='sm'>
<SelectValue>{getMatchLabel(phCond.mode)}</SelectValue>
</SelectTrigger>
<SelectContent>
{matchOptions.map((option) => (
<SelectItem key={option.value} value={option.value}>
{getMatchLabel(option.value)}
</SelectItem>
))}
<SelectContent alignItemWithTrigger={false}>
<SelectGroup>
{matchOptions.map((option) => (
<SelectItem key={option.value} value={option.value}>
{getMatchLabel(option.value)}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
{phCond.mode !== MATCH_EXISTS && (
@@ -1085,16 +1129,23 @@ function RuleConditionRow({
return (
<div className='flex flex-wrap items-center gap-2'>
<Select
items={[
{ value: SOURCE_PARAM, label: t('Body param') },
{ value: SOURCE_HEADER, label: t('Header') },
{ value: SOURCE_TIME, label: t('Time') },
]}
value={condition.source}
onValueChange={(v) => v !== null && handleSourceChange(v)}
>
<SelectTrigger className='w-28' size='sm'>
<SelectValue>{sourceLabel}</SelectValue>
</SelectTrigger>
<SelectContent>
<SelectItem value={SOURCE_PARAM}>{t('Body param')}</SelectItem>
<SelectItem value={SOURCE_HEADER}>{t('Header')}</SelectItem>
<SelectItem value={SOURCE_TIME}>{t('Time')}</SelectItem>
<SelectContent alignItemWithTrigger={false}>
<SelectGroup>
<SelectItem value={SOURCE_PARAM}>{t('Body param')}</SelectItem>
<SelectItem value={SOURCE_HEADER}>{t('Header')}</SelectItem>
<SelectItem value={SOURCE_TIME}>{t('Time')}</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
{condition.source === SOURCE_TIME
@@ -1705,15 +1756,21 @@ export const TieredPricingEditor = memo(function TieredPricingEditor({
<div className='flex items-center justify-between gap-2'>
<Label className='text-xs'>{t('Editor mode')}</Label>
<Select
items={[
{ value: 'visual', label: t('Visual editor') },
{ value: 'raw', label: t('Expression editor') },
]}
value={editorMode}
onValueChange={(value) => handleModeChange(value as EditorMode)}
>
<SelectTrigger className='w-44' size='sm'>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value='visual'>{t('Visual editor')}</SelectItem>
<SelectItem value='raw'>{t('Expression editor')}</SelectItem>
<SelectContent alignItemWithTrigger={false}>
<SelectGroup>
<SelectItem value='visual'>{t('Visual editor')}</SelectItem>
<SelectItem value='raw'>{t('Expression editor')}</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</div>
@@ -11,6 +11,7 @@ import { Input } from '@/components/ui/input'
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
@@ -212,6 +213,13 @@ export function UpstreamRatioSyncTable({
/>
</div>
<Select
items={[
{ value: '__all__', label: t('All Types') },
...RATIO_TYPE_OPTIONS.map((option) => ({
value: option.value,
label: t(option.label),
})),
]}
value={ratioTypeFilter}
onValueChange={(v) => v !== null && setRatioTypeFilter(v)}
disabled={isDisabled}
@@ -219,13 +227,15 @@ export function UpstreamRatioSyncTable({
<SelectTrigger className='w-full sm:w-56'>
<SelectValue placeholder={t('Filter by price field')} />
</SelectTrigger>
<SelectContent>
<SelectItem value='__all__'>{t('All Types')}</SelectItem>
{RATIO_TYPE_OPTIONS.map((option) => (
<SelectItem key={option.value} value={option.value}>
{t(option.label)}
</SelectItem>
))}
<SelectContent alignItemWithTrigger={false}>
<SelectGroup>
<SelectItem value='__all__'>{t('All Types')}</SelectItem>
{RATIO_TYPE_OPTIONS.map((option) => (
<SelectItem key={option.value} value={option.value}>
{t(option.label)}
</SelectItem>
))}
</SelectGroup>
</SelectContent>
</Select>
</div>