Skip to content

Commit bb3bd47

Browse files
committed
feat: 新增 FaRadioGroup 组件
1 parent 931b10c commit bb3bd47

14 files changed

Lines changed: 579 additions & 76 deletions

File tree

‎apps/example/src/router/modules/component.example.ts‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,14 @@ const routes: RouteRecordRaw = {
222222
title: '进度条',
223223
},
224224
},
225+
{
226+
path: 'radio_group',
227+
name: 'componentExampleRadioGroup',
228+
component: () => import('@/views/component_example/radio_group/index.vue'),
229+
meta: {
230+
title: '单选组',
231+
},
232+
},
225233
{
226234
path: 'scroll_area',
227235
name: 'componentExampleScrollArea',

‎apps/example/src/types/components.d.ts‎

100755100644
Lines changed: 2 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -19,82 +19,45 @@ declare module 'vue' {
1919
AppNotAllowed: typeof import('./../components/AppNotAllowed/index.vue')['default']
2020
AppNotSupportedMobile: typeof import('./../components/AppNotSupportedMobile/index.vue')['default']
2121
AppSystemInfo: typeof import('./../components/AppSystemInfo/index.vue')['default']
22-
FaAnimatedBeam: typeof import('@fantastic-admin/components')['FaAnimatedBeam']
23-
FaAnimatedCountTo: typeof import('@fantastic-admin/components')['FaAnimatedCountTo']
24-
FaAnimatedCountToGroup: typeof import('@fantastic-admin/components')['FaAnimatedCountToGroup']
2522
FaAvatar: typeof import('@fantastic-admin/components')['FaAvatar']
26-
FaBlurReveal: typeof import('@fantastic-admin/components')['FaBlurReveal']
27-
FaBorderBeam: typeof import('@fantastic-admin/components')['FaBorderBeam']
2823
FaButton: typeof import('@fantastic-admin/components')['FaButton']
2924
FaButtonGroup: typeof import('@fantastic-admin/components')['FaButtonGroup']
3025
FaCard: typeof import('@fantastic-admin/components')['FaCard']
31-
FaCarousel: typeof import('@fantastic-admin/components')['FaCarousel']
32-
FaCascader: typeof import('@fantastic-admin/components')['FaCascader']
3326
FaCheckbox: typeof import('@fantastic-admin/components')['FaCheckbox']
34-
FaCode: typeof import('@fantastic-admin/components')['FaCode']
35-
FaCodePreview: typeof import('@fantastic-admin/components')['FaCodePreview']
3627
FaCollapsible: typeof import('@fantastic-admin/components')['FaCollapsible']
3728
FaContextMenu: typeof import('@fantastic-admin/components')['FaContextMenu']
38-
FaCountTo: typeof import('@fantastic-admin/components')['FaCountTo']
39-
FaDigitalCard: typeof import('@fantastic-admin/components')['FaDigitalCard']
4029
FaDivider: typeof import('@fantastic-admin/components')['FaDivider']
4130
FaDrawer: typeof import('@fantastic-admin/components')['FaDrawer']
4231
FaDropdown: typeof import('@fantastic-admin/components')['FaDropdown']
43-
FaEmpty: typeof import('@fantastic-admin/components')['FaEmpty']
4432
FaFileUpload: typeof import('@fantastic-admin/components')['FaFileUpload']
4533
FaFixedBar: typeof import('@fantastic-admin/components')['FaFixedBar']
46-
FaFlipCard: typeof import('@fantastic-admin/components')['FaFlipCard']
47-
FaFlipWords: typeof import('@fantastic-admin/components')['FaFlipWords']
48-
FaGlowyCard: typeof import('@fantastic-admin/components')['FaGlowyCard']
49-
FaGlowyCardWrapper: typeof import('@fantastic-admin/components')['FaGlowyCardWrapper']
50-
FaGradientButton: typeof import('@fantastic-admin/components')['FaGradientButton']
5134
FaHoverCard: typeof import('@fantastic-admin/components')['FaHoverCard']
5235
FaIcon: typeof import('@fantastic-admin/components')['FaIcon']
53-
FaIconPicker: typeof import('@fantastic-admin/components')['FaIconPicker']
5436
FaImagePreview: typeof import('@fantastic-admin/components')['FaImagePreview']
5537
FaImageUpload: typeof import('@fantastic-admin/components')['FaImageUpload']
5638
FaInput: typeof import('@fantastic-admin/components')['FaInput']
5739
FaInputOTP: typeof import('@fantastic-admin/components')['FaInputOTP']
58-
FaInteractiveButton: typeof import('@fantastic-admin/components')['FaInteractiveButton']
5940
FaKbd: typeof import('@fantastic-admin/components')['FaKbd']
6041
FaKbdGroup: typeof import('@fantastic-admin/components')['FaKbdGroup']
6142
FaLabel: typeof import('@fantastic-admin/components')['FaLabel']
62-
FaLayoutContainer: typeof import('@fantastic-admin/components')['FaLayoutContainer']
63-
FaLinkPreview: typeof import('@fantastic-admin/components')['FaLinkPreview']
64-
FaLoading: typeof import('@fantastic-admin/components')['FaLoading']
65-
FaMarquee: typeof import('@fantastic-admin/components')['FaMarquee']
6643
FaModal: typeof import('@fantastic-admin/components')['FaModal']
67-
FaMultiStepLoader: typeof import('@fantastic-admin/components')['FaMultiStepLoader']
6844
FaNumberField: typeof import('@fantastic-admin/components')['FaNumberField']
6945
FaPageHeader: typeof import('@fantastic-admin/components')['FaPageHeader']
7046
FaPageMain: typeof import('@fantastic-admin/components')['FaPageMain']
7147
FaPagination: typeof import('@fantastic-admin/components')['FaPagination']
72-
FaParticlesBg: typeof import('@fantastic-admin/components')['FaParticlesBg']
7348
FaPasswordStrength: typeof import('@fantastic-admin/components')['FaPasswordStrength']
74-
FaPatternBg: typeof import('@fantastic-admin/components')['FaPatternBg']
7549
FaPopover: typeof import('@fantastic-admin/components')['FaPopover']
7650
FaProgress: typeof import('@fantastic-admin/components')['FaProgress']
77-
FaQrcode: typeof import('@fantastic-admin/components')['FaQrcode']
78-
FaScratchOff: typeof import('@fantastic-admin/components')['FaScratchOff']
51+
FaRadioGroup: typeof import('@fantastic-admin/components')['FaRadioGroup']
7952
FaScrollArea: typeof import('@fantastic-admin/components')['FaScrollArea']
80-
FaScrollingText: typeof import('@fantastic-admin/components')['FaScrollingText']
8153
FaSearchBar: typeof import('@fantastic-admin/components')['FaSearchBar']
8254
FaSelect: typeof import('@fantastic-admin/components')['FaSelect']
8355
FaSlider: typeof import('@fantastic-admin/components')['FaSlider']
84-
FaSmoothSwipe: typeof import('@fantastic-admin/components')['FaSmoothSwipe']
85-
FaSparklesText: typeof import('@fantastic-admin/components')['FaSparklesText']
86-
FaSparkline: typeof import('@fantastic-admin/components')['FaSparkline']
87-
FaSpotlightCard: typeof import('@fantastic-admin/components')['FaSpotlightCard']
88-
FaStorageBox: typeof import('@fantastic-admin/components')['FaStorageBox']
8956
FaSwitch: typeof import('@fantastic-admin/components')['FaSwitch']
9057
FaTabs: typeof import('@fantastic-admin/components')['FaTabs']
9158
FaTextarea: typeof import('@fantastic-admin/components')['FaTextarea']
92-
FaTextHighlight: typeof import('@fantastic-admin/components')['FaTextHighlight']
93-
FaTimeAgo: typeof import('@fantastic-admin/components')['FaTimeAgo']
94-
FaTimeline: typeof import('@fantastic-admin/components')['FaTimeline']
9559
FaToast: typeof import('@fantastic-admin/components')['FaToast']
9660
FaTooltip: typeof import('@fantastic-admin/components')['FaTooltip']
97-
FaTree: typeof import('@fantastic-admin/components')['FaTree']
9861
FaTrend: typeof import('@fantastic-admin/components')['FaTrend']
9962
}
10063
}
@@ -108,81 +71,44 @@ declare global {
10871
const AppNotAllowed: typeof import('./../components/AppNotAllowed/index.vue')['default']
10972
const AppNotSupportedMobile: typeof import('./../components/AppNotSupportedMobile/index.vue')['default']
11073
const AppSystemInfo: typeof import('./../components/AppSystemInfo/index.vue')['default']
111-
const FaAnimatedBeam: typeof import('@fantastic-admin/components')['FaAnimatedBeam']
112-
const FaAnimatedCountTo: typeof import('@fantastic-admin/components')['FaAnimatedCountTo']
113-
const FaAnimatedCountToGroup: typeof import('@fantastic-admin/components')['FaAnimatedCountToGroup']
11474
const FaAvatar: typeof import('@fantastic-admin/components')['FaAvatar']
115-
const FaBlurReveal: typeof import('@fantastic-admin/components')['FaBlurReveal']
116-
const FaBorderBeam: typeof import('@fantastic-admin/components')['FaBorderBeam']
11775
const FaButton: typeof import('@fantastic-admin/components')['FaButton']
11876
const FaButtonGroup: typeof import('@fantastic-admin/components')['FaButtonGroup']
11977
const FaCard: typeof import('@fantastic-admin/components')['FaCard']
120-
const FaCarousel: typeof import('@fantastic-admin/components')['FaCarousel']
121-
const FaCascader: typeof import('@fantastic-admin/components')['FaCascader']
12278
const FaCheckbox: typeof import('@fantastic-admin/components')['FaCheckbox']
123-
const FaCode: typeof import('@fantastic-admin/components')['FaCode']
124-
const FaCodePreview: typeof import('@fantastic-admin/components')['FaCodePreview']
12579
const FaCollapsible: typeof import('@fantastic-admin/components')['FaCollapsible']
12680
const FaContextMenu: typeof import('@fantastic-admin/components')['FaContextMenu']
127-
const FaCountTo: typeof import('@fantastic-admin/components')['FaCountTo']
128-
const FaDigitalCard: typeof import('@fantastic-admin/components')['FaDigitalCard']
12981
const FaDivider: typeof import('@fantastic-admin/components')['FaDivider']
13082
const FaDrawer: typeof import('@fantastic-admin/components')['FaDrawer']
13183
const FaDropdown: typeof import('@fantastic-admin/components')['FaDropdown']
132-
const FaEmpty: typeof import('@fantastic-admin/components')['FaEmpty']
13384
const FaFileUpload: typeof import('@fantastic-admin/components')['FaFileUpload']
13485
const FaFixedBar: typeof import('@fantastic-admin/components')['FaFixedBar']
135-
const FaFlipCard: typeof import('@fantastic-admin/components')['FaFlipCard']
136-
const FaFlipWords: typeof import('@fantastic-admin/components')['FaFlipWords']
137-
const FaGlowyCard: typeof import('@fantastic-admin/components')['FaGlowyCard']
138-
const FaGlowyCardWrapper: typeof import('@fantastic-admin/components')['FaGlowyCardWrapper']
139-
const FaGradientButton: typeof import('@fantastic-admin/components')['FaGradientButton']
14086
const FaHoverCard: typeof import('@fantastic-admin/components')['FaHoverCard']
14187
const FaIcon: typeof import('@fantastic-admin/components')['FaIcon']
142-
const FaIconPicker: typeof import('@fantastic-admin/components')['FaIconPicker']
14388
const FaImagePreview: typeof import('@fantastic-admin/components')['FaImagePreview']
14489
const FaImageUpload: typeof import('@fantastic-admin/components')['FaImageUpload']
14590
const FaInput: typeof import('@fantastic-admin/components')['FaInput']
14691
const FaInputOTP: typeof import('@fantastic-admin/components')['FaInputOTP']
147-
const FaInteractiveButton: typeof import('@fantastic-admin/components')['FaInteractiveButton']
14892
const FaKbd: typeof import('@fantastic-admin/components')['FaKbd']
14993
const FaKbdGroup: typeof import('@fantastic-admin/components')['FaKbdGroup']
15094
const FaLabel: typeof import('@fantastic-admin/components')['FaLabel']
151-
const FaLayoutContainer: typeof import('@fantastic-admin/components')['FaLayoutContainer']
152-
const FaLinkPreview: typeof import('@fantastic-admin/components')['FaLinkPreview']
153-
const FaLoading: typeof import('@fantastic-admin/components')['FaLoading']
154-
const FaMarquee: typeof import('@fantastic-admin/components')['FaMarquee']
15595
const FaModal: typeof import('@fantastic-admin/components')['FaModal']
156-
const FaMultiStepLoader: typeof import('@fantastic-admin/components')['FaMultiStepLoader']
15796
const FaNumberField: typeof import('@fantastic-admin/components')['FaNumberField']
15897
const FaPageHeader: typeof import('@fantastic-admin/components')['FaPageHeader']
15998
const FaPageMain: typeof import('@fantastic-admin/components')['FaPageMain']
16099
const FaPagination: typeof import('@fantastic-admin/components')['FaPagination']
161-
const FaParticlesBg: typeof import('@fantastic-admin/components')['FaParticlesBg']
162100
const FaPasswordStrength: typeof import('@fantastic-admin/components')['FaPasswordStrength']
163-
const FaPatternBg: typeof import('@fantastic-admin/components')['FaPatternBg']
164101
const FaPopover: typeof import('@fantastic-admin/components')['FaPopover']
165102
const FaProgress: typeof import('@fantastic-admin/components')['FaProgress']
166-
const FaQrcode: typeof import('@fantastic-admin/components')['FaQrcode']
167-
const FaScratchOff: typeof import('@fantastic-admin/components')['FaScratchOff']
103+
const FaRadioGroup: typeof import('@fantastic-admin/components')['FaRadioGroup']
168104
const FaScrollArea: typeof import('@fantastic-admin/components')['FaScrollArea']
169-
const FaScrollingText: typeof import('@fantastic-admin/components')['FaScrollingText']
170105
const FaSearchBar: typeof import('@fantastic-admin/components')['FaSearchBar']
171106
const FaSelect: typeof import('@fantastic-admin/components')['FaSelect']
172107
const FaSlider: typeof import('@fantastic-admin/components')['FaSlider']
173-
const FaSmoothSwipe: typeof import('@fantastic-admin/components')['FaSmoothSwipe']
174-
const FaSparklesText: typeof import('@fantastic-admin/components')['FaSparklesText']
175-
const FaSparkline: typeof import('@fantastic-admin/components')['FaSparkline']
176-
const FaSpotlightCard: typeof import('@fantastic-admin/components')['FaSpotlightCard']
177-
const FaStorageBox: typeof import('@fantastic-admin/components')['FaStorageBox']
178108
const FaSwitch: typeof import('@fantastic-admin/components')['FaSwitch']
179109
const FaTabs: typeof import('@fantastic-admin/components')['FaTabs']
180110
const FaTextarea: typeof import('@fantastic-admin/components')['FaTextarea']
181-
const FaTextHighlight: typeof import('@fantastic-admin/components')['FaTextHighlight']
182-
const FaTimeAgo: typeof import('@fantastic-admin/components')['FaTimeAgo']
183-
const FaTimeline: typeof import('@fantastic-admin/components')['FaTimeline']
184111
const FaToast: typeof import('@fantastic-admin/components')['FaToast']
185112
const FaTooltip: typeof import('@fantastic-admin/components')['FaTooltip']
186-
const FaTree: typeof import('@fantastic-admin/components')['FaTree']
187113
const FaTrend: typeof import('@fantastic-admin/components')['FaTrend']
188114
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<script setup lang="ts">
2+
const value = ref('comfortable')
3+
4+
const options = [
5+
{ label: '默认', value: 'default' },
6+
{ label: '舒适', value: 'comfortable' },
7+
{ label: '紧凑', value: 'compact' },
8+
]
9+
</script>
10+
11+
<template>
12+
<div class="gap-4 grid">
13+
<FaRadioGroup v-model="value" :options="options" />
14+
<div class="text-sm text-muted-foreground">
15+
当前值:{{ value }}
16+
</div>
17+
</div>
18+
</template>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<script setup lang="ts">
2+
const value = ref('growth')
3+
4+
const options = [
5+
{
6+
label: '创业版',
7+
value: 'starter',
8+
description: '适合 1-10 人小团队,保留核心能力。',
9+
},
10+
{
11+
label: '成长版',
12+
value: 'growth',
13+
description: '适合多角色协作,支持审批与审计流程。',
14+
},
15+
{
16+
label: '企业版',
17+
value: 'enterprise',
18+
description: '高级安全策略与 SSO 即将开放。',
19+
disabled: true,
20+
},
21+
]
22+
23+
const currentLabel = computed(() =>
24+
options.find(option => option.value === value.value)?.label ?? '',
25+
)
26+
</script>
27+
28+
<template>
29+
<div class="gap-4 grid">
30+
<FaRadioGroup v-model="value" :options="options" />
31+
<div class="text-sm text-muted-foreground">
32+
已选套餐:{{ currentLabel }}
33+
</div>
34+
</div>
35+
</template>
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<script setup lang="ts">
2+
const value = ref('balanced')
3+
4+
const options = [
5+
{
6+
label: '专注模式',
7+
value: 'focus',
8+
description: '突出主任务,弱化辅助信息,适合录入和审批场景。',
9+
},
10+
{
11+
label: '平衡模式',
12+
value: 'balanced',
13+
description: '信息密度与可读性保持平衡,适合作为默认配置。',
14+
},
15+
{
16+
label: '高密度模式',
17+
value: 'dense',
18+
description: '在大屏中同时承载更多信息,适合运营与监控看板。',
19+
},
20+
]
21+
22+
const currentLabel = computed(() =>
23+
options.find(option => option.value === value.value)?.label ?? '',
24+
)
25+
</script>
26+
27+
<template>
28+
<div class="gap-4 grid">
29+
<FaRadioGroup
30+
v-model="value"
31+
orientation="horizontal"
32+
:options="options"
33+
class="gap-4 md:grid-cols-3"
34+
option-class="rounded-xl border border-transparent px-1 py-1"
35+
item-class="mt-1"
36+
>
37+
<template #option="{ option, checked, disabled }">
38+
<div
39+
class="px-4 py-3 border rounded-xl flex gap-3 w-full transition-colors items-start justify-between" :class="[
40+
checked ? 'border-primary bg-primary/5' : 'border-border hover:border-primary/40',
41+
disabled && 'opacity-60',
42+
]"
43+
>
44+
<div class="gap-1 grid min-w-0">
45+
<div class="text-sm font-medium truncate">
46+
{{ option.label }}
47+
</div>
48+
<div
49+
v-if="option.description"
50+
class="text-xs text-muted-foreground leading-5"
51+
>
52+
{{ option.description }}
53+
</div>
54+
</div>
55+
<span
56+
class="text-xs font-medium shrink-0" :class="[
57+
checked ? 'text-primary' : 'text-muted-foreground',
58+
]"
59+
>
60+
{{ checked ? '已选中' : '可选择' }}
61+
</span>
62+
</div>
63+
</template>
64+
</FaRadioGroup>
65+
<div class="text-sm text-muted-foreground">
66+
当前模式:{{ currentLabel }}
67+
</div>
68+
</div>
69+
</template>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<script setup lang="ts">
2+
import Demo1 from './_demo1.vue'
3+
import Demo2 from './_demo2.vue'
4+
import Demo3 from './_demo3.vue'
5+
</script>
6+
7+
<template>
8+
<div>
9+
<FaPageHeader title="单选组" description="FaRadioGroup" />
10+
<FaPageMain main-class="p-4">
11+
<Demo1 />
12+
</FaPageMain>
13+
<FaPageMain title="带描述和禁用态" main-class="p-4">
14+
<Demo2 />
15+
</FaPageMain>
16+
<FaPageMain title="自定义选项内容" main-class="p-4">
17+
<Demo3 />
18+
</FaPageMain>
19+
</div>
20+
</template>

‎packages/components/global.d.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ declare module 'vue' {
2828
FaPasswordStrength: typeof import('./index')['FaPasswordStrength']
2929
FaPopover: typeof import('./index')['FaPopover']
3030
FaProgress: typeof import('./index')['FaProgress']
31+
FaRadioGroup: typeof import('./index')['FaRadioGroup']
3132
FaScrollArea: typeof import('./index')['FaScrollArea']
3233
FaSearchBar: typeof import('./index')['FaSearchBar']
3334
FaSelect: typeof import('./index')['FaSelect']

‎packages/components/index.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export { default as FaPagination } from './src/pagination/index.vue'
3131
export { default as FaPasswordStrength } from './src/password-strength/index.vue'
3232
export { default as FaPopover } from './src/popover/index.vue'
3333
export { default as FaProgress } from './src/progress/index.vue'
34+
export { default as FaRadioGroup } from './src/radio-group/index.vue'
3435
export { default as FaScrollArea } from './src/scroll-area/index.vue'
3536
export { default as FaSearchBar } from './src/search-bar/index.vue'
3637
export { default as FaSelect } from './src/select/index.vue'

‎packages/components/resolver.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const COMPONENT_NAMES = [
3434
'FaPasswordStrength',
3535
'FaPopover',
3636
'FaProgress',
37+
'FaRadioGroup',
3738
'FaScrollArea',
3839
'FaSearchBar',
3940
'FaSelect',

0 commit comments

Comments
 (0)