diff --git a/apps/example/src/router/modules/component.example.ts b/apps/example/src/router/modules/component.example.ts index f8a47d85..3cca500e 100755 --- a/apps/example/src/router/modules/component.example.ts +++ b/apps/example/src/router/modules/component.example.ts @@ -222,6 +222,14 @@ const routes: RouteRecordRaw = { title: '进度条', }, }, + { + path: 'radio_group', + name: 'componentExampleRadioGroup', + component: () => import('@/views/component_example/radio_group/index.vue'), + meta: { + title: '单选组', + }, + }, { path: 'scroll_area', name: 'componentExampleScrollArea', diff --git a/apps/example/src/types/components.d.ts b/apps/example/src/types/components.d.ts old mode 100755 new mode 100644 index f896644a..291f7014 --- a/apps/example/src/types/components.d.ts +++ b/apps/example/src/types/components.d.ts @@ -19,82 +19,45 @@ declare module 'vue' { AppNotAllowed: typeof import('./../components/AppNotAllowed/index.vue')['default'] AppNotSupportedMobile: typeof import('./../components/AppNotSupportedMobile/index.vue')['default'] AppSystemInfo: typeof import('./../components/AppSystemInfo/index.vue')['default'] - FaAnimatedBeam: typeof import('@fantastic-admin/components')['FaAnimatedBeam'] - FaAnimatedCountTo: typeof import('@fantastic-admin/components')['FaAnimatedCountTo'] - FaAnimatedCountToGroup: typeof import('@fantastic-admin/components')['FaAnimatedCountToGroup'] FaAvatar: typeof import('@fantastic-admin/components')['FaAvatar'] - FaBlurReveal: typeof import('@fantastic-admin/components')['FaBlurReveal'] - FaBorderBeam: typeof import('@fantastic-admin/components')['FaBorderBeam'] FaButton: typeof import('@fantastic-admin/components')['FaButton'] FaButtonGroup: typeof import('@fantastic-admin/components')['FaButtonGroup'] FaCard: typeof import('@fantastic-admin/components')['FaCard'] - FaCarousel: typeof import('@fantastic-admin/components')['FaCarousel'] - FaCascader: typeof import('@fantastic-admin/components')['FaCascader'] FaCheckbox: typeof import('@fantastic-admin/components')['FaCheckbox'] - FaCode: typeof import('@fantastic-admin/components')['FaCode'] - FaCodePreview: typeof import('@fantastic-admin/components')['FaCodePreview'] FaCollapsible: typeof import('@fantastic-admin/components')['FaCollapsible'] FaContextMenu: typeof import('@fantastic-admin/components')['FaContextMenu'] - FaCountTo: typeof import('@fantastic-admin/components')['FaCountTo'] - FaDigitalCard: typeof import('@fantastic-admin/components')['FaDigitalCard'] FaDivider: typeof import('@fantastic-admin/components')['FaDivider'] FaDrawer: typeof import('@fantastic-admin/components')['FaDrawer'] FaDropdown: typeof import('@fantastic-admin/components')['FaDropdown'] - FaEmpty: typeof import('@fantastic-admin/components')['FaEmpty'] FaFileUpload: typeof import('@fantastic-admin/components')['FaFileUpload'] FaFixedBar: typeof import('@fantastic-admin/components')['FaFixedBar'] - FaFlipCard: typeof import('@fantastic-admin/components')['FaFlipCard'] - FaFlipWords: typeof import('@fantastic-admin/components')['FaFlipWords'] - FaGlowyCard: typeof import('@fantastic-admin/components')['FaGlowyCard'] - FaGlowyCardWrapper: typeof import('@fantastic-admin/components')['FaGlowyCardWrapper'] - FaGradientButton: typeof import('@fantastic-admin/components')['FaGradientButton'] FaHoverCard: typeof import('@fantastic-admin/components')['FaHoverCard'] FaIcon: typeof import('@fantastic-admin/components')['FaIcon'] - FaIconPicker: typeof import('@fantastic-admin/components')['FaIconPicker'] FaImagePreview: typeof import('@fantastic-admin/components')['FaImagePreview'] FaImageUpload: typeof import('@fantastic-admin/components')['FaImageUpload'] FaInput: typeof import('@fantastic-admin/components')['FaInput'] FaInputOTP: typeof import('@fantastic-admin/components')['FaInputOTP'] - FaInteractiveButton: typeof import('@fantastic-admin/components')['FaInteractiveButton'] FaKbd: typeof import('@fantastic-admin/components')['FaKbd'] FaKbdGroup: typeof import('@fantastic-admin/components')['FaKbdGroup'] FaLabel: typeof import('@fantastic-admin/components')['FaLabel'] - FaLayoutContainer: typeof import('@fantastic-admin/components')['FaLayoutContainer'] - FaLinkPreview: typeof import('@fantastic-admin/components')['FaLinkPreview'] - FaLoading: typeof import('@fantastic-admin/components')['FaLoading'] - FaMarquee: typeof import('@fantastic-admin/components')['FaMarquee'] FaModal: typeof import('@fantastic-admin/components')['FaModal'] - FaMultiStepLoader: typeof import('@fantastic-admin/components')['FaMultiStepLoader'] FaNumberField: typeof import('@fantastic-admin/components')['FaNumberField'] FaPageHeader: typeof import('@fantastic-admin/components')['FaPageHeader'] FaPageMain: typeof import('@fantastic-admin/components')['FaPageMain'] FaPagination: typeof import('@fantastic-admin/components')['FaPagination'] - FaParticlesBg: typeof import('@fantastic-admin/components')['FaParticlesBg'] FaPasswordStrength: typeof import('@fantastic-admin/components')['FaPasswordStrength'] - FaPatternBg: typeof import('@fantastic-admin/components')['FaPatternBg'] FaPopover: typeof import('@fantastic-admin/components')['FaPopover'] FaProgress: typeof import('@fantastic-admin/components')['FaProgress'] - FaQrcode: typeof import('@fantastic-admin/components')['FaQrcode'] - FaScratchOff: typeof import('@fantastic-admin/components')['FaScratchOff'] + FaRadioGroup: typeof import('@fantastic-admin/components')['FaRadioGroup'] FaScrollArea: typeof import('@fantastic-admin/components')['FaScrollArea'] - FaScrollingText: typeof import('@fantastic-admin/components')['FaScrollingText'] FaSearchBar: typeof import('@fantastic-admin/components')['FaSearchBar'] FaSelect: typeof import('@fantastic-admin/components')['FaSelect'] FaSlider: typeof import('@fantastic-admin/components')['FaSlider'] - FaSmoothSwipe: typeof import('@fantastic-admin/components')['FaSmoothSwipe'] - FaSparklesText: typeof import('@fantastic-admin/components')['FaSparklesText'] - FaSparkline: typeof import('@fantastic-admin/components')['FaSparkline'] - FaSpotlightCard: typeof import('@fantastic-admin/components')['FaSpotlightCard'] - FaStorageBox: typeof import('@fantastic-admin/components')['FaStorageBox'] FaSwitch: typeof import('@fantastic-admin/components')['FaSwitch'] FaTabs: typeof import('@fantastic-admin/components')['FaTabs'] FaTextarea: typeof import('@fantastic-admin/components')['FaTextarea'] - FaTextHighlight: typeof import('@fantastic-admin/components')['FaTextHighlight'] - FaTimeAgo: typeof import('@fantastic-admin/components')['FaTimeAgo'] - FaTimeline: typeof import('@fantastic-admin/components')['FaTimeline'] FaToast: typeof import('@fantastic-admin/components')['FaToast'] FaTooltip: typeof import('@fantastic-admin/components')['FaTooltip'] - FaTree: typeof import('@fantastic-admin/components')['FaTree'] FaTrend: typeof import('@fantastic-admin/components')['FaTrend'] } } @@ -108,81 +71,44 @@ declare global { const AppNotAllowed: typeof import('./../components/AppNotAllowed/index.vue')['default'] const AppNotSupportedMobile: typeof import('./../components/AppNotSupportedMobile/index.vue')['default'] const AppSystemInfo: typeof import('./../components/AppSystemInfo/index.vue')['default'] - const FaAnimatedBeam: typeof import('@fantastic-admin/components')['FaAnimatedBeam'] - const FaAnimatedCountTo: typeof import('@fantastic-admin/components')['FaAnimatedCountTo'] - const FaAnimatedCountToGroup: typeof import('@fantastic-admin/components')['FaAnimatedCountToGroup'] const FaAvatar: typeof import('@fantastic-admin/components')['FaAvatar'] - const FaBlurReveal: typeof import('@fantastic-admin/components')['FaBlurReveal'] - const FaBorderBeam: typeof import('@fantastic-admin/components')['FaBorderBeam'] const FaButton: typeof import('@fantastic-admin/components')['FaButton'] const FaButtonGroup: typeof import('@fantastic-admin/components')['FaButtonGroup'] const FaCard: typeof import('@fantastic-admin/components')['FaCard'] - const FaCarousel: typeof import('@fantastic-admin/components')['FaCarousel'] - const FaCascader: typeof import('@fantastic-admin/components')['FaCascader'] const FaCheckbox: typeof import('@fantastic-admin/components')['FaCheckbox'] - const FaCode: typeof import('@fantastic-admin/components')['FaCode'] - const FaCodePreview: typeof import('@fantastic-admin/components')['FaCodePreview'] const FaCollapsible: typeof import('@fantastic-admin/components')['FaCollapsible'] const FaContextMenu: typeof import('@fantastic-admin/components')['FaContextMenu'] - const FaCountTo: typeof import('@fantastic-admin/components')['FaCountTo'] - const FaDigitalCard: typeof import('@fantastic-admin/components')['FaDigitalCard'] const FaDivider: typeof import('@fantastic-admin/components')['FaDivider'] const FaDrawer: typeof import('@fantastic-admin/components')['FaDrawer'] const FaDropdown: typeof import('@fantastic-admin/components')['FaDropdown'] - const FaEmpty: typeof import('@fantastic-admin/components')['FaEmpty'] const FaFileUpload: typeof import('@fantastic-admin/components')['FaFileUpload'] const FaFixedBar: typeof import('@fantastic-admin/components')['FaFixedBar'] - const FaFlipCard: typeof import('@fantastic-admin/components')['FaFlipCard'] - const FaFlipWords: typeof import('@fantastic-admin/components')['FaFlipWords'] - const FaGlowyCard: typeof import('@fantastic-admin/components')['FaGlowyCard'] - const FaGlowyCardWrapper: typeof import('@fantastic-admin/components')['FaGlowyCardWrapper'] - const FaGradientButton: typeof import('@fantastic-admin/components')['FaGradientButton'] const FaHoverCard: typeof import('@fantastic-admin/components')['FaHoverCard'] const FaIcon: typeof import('@fantastic-admin/components')['FaIcon'] - const FaIconPicker: typeof import('@fantastic-admin/components')['FaIconPicker'] const FaImagePreview: typeof import('@fantastic-admin/components')['FaImagePreview'] const FaImageUpload: typeof import('@fantastic-admin/components')['FaImageUpload'] const FaInput: typeof import('@fantastic-admin/components')['FaInput'] const FaInputOTP: typeof import('@fantastic-admin/components')['FaInputOTP'] - const FaInteractiveButton: typeof import('@fantastic-admin/components')['FaInteractiveButton'] const FaKbd: typeof import('@fantastic-admin/components')['FaKbd'] const FaKbdGroup: typeof import('@fantastic-admin/components')['FaKbdGroup'] const FaLabel: typeof import('@fantastic-admin/components')['FaLabel'] - const FaLayoutContainer: typeof import('@fantastic-admin/components')['FaLayoutContainer'] - const FaLinkPreview: typeof import('@fantastic-admin/components')['FaLinkPreview'] - const FaLoading: typeof import('@fantastic-admin/components')['FaLoading'] - const FaMarquee: typeof import('@fantastic-admin/components')['FaMarquee'] const FaModal: typeof import('@fantastic-admin/components')['FaModal'] - const FaMultiStepLoader: typeof import('@fantastic-admin/components')['FaMultiStepLoader'] const FaNumberField: typeof import('@fantastic-admin/components')['FaNumberField'] const FaPageHeader: typeof import('@fantastic-admin/components')['FaPageHeader'] const FaPageMain: typeof import('@fantastic-admin/components')['FaPageMain'] const FaPagination: typeof import('@fantastic-admin/components')['FaPagination'] - const FaParticlesBg: typeof import('@fantastic-admin/components')['FaParticlesBg'] const FaPasswordStrength: typeof import('@fantastic-admin/components')['FaPasswordStrength'] - const FaPatternBg: typeof import('@fantastic-admin/components')['FaPatternBg'] const FaPopover: typeof import('@fantastic-admin/components')['FaPopover'] const FaProgress: typeof import('@fantastic-admin/components')['FaProgress'] - const FaQrcode: typeof import('@fantastic-admin/components')['FaQrcode'] - const FaScratchOff: typeof import('@fantastic-admin/components')['FaScratchOff'] + const FaRadioGroup: typeof import('@fantastic-admin/components')['FaRadioGroup'] const FaScrollArea: typeof import('@fantastic-admin/components')['FaScrollArea'] - const FaScrollingText: typeof import('@fantastic-admin/components')['FaScrollingText'] const FaSearchBar: typeof import('@fantastic-admin/components')['FaSearchBar'] const FaSelect: typeof import('@fantastic-admin/components')['FaSelect'] const FaSlider: typeof import('@fantastic-admin/components')['FaSlider'] - const FaSmoothSwipe: typeof import('@fantastic-admin/components')['FaSmoothSwipe'] - const FaSparklesText: typeof import('@fantastic-admin/components')['FaSparklesText'] - const FaSparkline: typeof import('@fantastic-admin/components')['FaSparkline'] - const FaSpotlightCard: typeof import('@fantastic-admin/components')['FaSpotlightCard'] - const FaStorageBox: typeof import('@fantastic-admin/components')['FaStorageBox'] const FaSwitch: typeof import('@fantastic-admin/components')['FaSwitch'] const FaTabs: typeof import('@fantastic-admin/components')['FaTabs'] const FaTextarea: typeof import('@fantastic-admin/components')['FaTextarea'] - const FaTextHighlight: typeof import('@fantastic-admin/components')['FaTextHighlight'] - const FaTimeAgo: typeof import('@fantastic-admin/components')['FaTimeAgo'] - const FaTimeline: typeof import('@fantastic-admin/components')['FaTimeline'] const FaToast: typeof import('@fantastic-admin/components')['FaToast'] const FaTooltip: typeof import('@fantastic-admin/components')['FaTooltip'] - const FaTree: typeof import('@fantastic-admin/components')['FaTree'] const FaTrend: typeof import('@fantastic-admin/components')['FaTrend'] } \ No newline at end of file diff --git a/apps/example/src/views/component_example/radio_group/_demo1.vue b/apps/example/src/views/component_example/radio_group/_demo1.vue new file mode 100644 index 00000000..a8b5ac89 --- /dev/null +++ b/apps/example/src/views/component_example/radio_group/_demo1.vue @@ -0,0 +1,18 @@ + + + + + + + 当前值:{{ value }} + + + diff --git a/apps/example/src/views/component_example/radio_group/_demo2.vue b/apps/example/src/views/component_example/radio_group/_demo2.vue new file mode 100644 index 00000000..b4e9cd91 --- /dev/null +++ b/apps/example/src/views/component_example/radio_group/_demo2.vue @@ -0,0 +1,35 @@ + + + + + + + 已选套餐:{{ currentLabel }} + + + diff --git a/apps/example/src/views/component_example/radio_group/_demo3.vue b/apps/example/src/views/component_example/radio_group/_demo3.vue new file mode 100644 index 00000000..317e78b6 --- /dev/null +++ b/apps/example/src/views/component_example/radio_group/_demo3.vue @@ -0,0 +1,69 @@ + + + + + + + + + + {{ option.label }} + + + {{ option.description }} + + + + {{ checked ? '已选中' : '可选择' }} + + + + + + 当前模式:{{ currentLabel }} + + + diff --git a/apps/example/src/views/component_example/radio_group/index.vue b/apps/example/src/views/component_example/radio_group/index.vue new file mode 100644 index 00000000..85b22b68 --- /dev/null +++ b/apps/example/src/views/component_example/radio_group/index.vue @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + diff --git a/packages/components/global.d.ts b/packages/components/global.d.ts index 049e35d6..0cb627e5 100755 --- a/packages/components/global.d.ts +++ b/packages/components/global.d.ts @@ -28,6 +28,7 @@ declare module 'vue' { FaPasswordStrength: typeof import('./index')['FaPasswordStrength'] FaPopover: typeof import('./index')['FaPopover'] FaProgress: typeof import('./index')['FaProgress'] + FaRadioGroup: typeof import('./index')['FaRadioGroup'] FaScrollArea: typeof import('./index')['FaScrollArea'] FaSearchBar: typeof import('./index')['FaSearchBar'] FaSelect: typeof import('./index')['FaSelect'] diff --git a/packages/components/index.ts b/packages/components/index.ts index caa411fe..676908e2 100755 --- a/packages/components/index.ts +++ b/packages/components/index.ts @@ -31,6 +31,7 @@ export { default as FaPagination } from './src/pagination/index.vue' export { default as FaPasswordStrength } from './src/password-strength/index.vue' export { default as FaPopover } from './src/popover/index.vue' export { default as FaProgress } from './src/progress/index.vue' +export { default as FaRadioGroup } from './src/radio-group/index.vue' export { default as FaScrollArea } from './src/scroll-area/index.vue' export { default as FaSearchBar } from './src/search-bar/index.vue' export { default as FaSelect } from './src/select/index.vue' diff --git a/packages/components/resolver.ts b/packages/components/resolver.ts index a8557332..f5413edc 100755 --- a/packages/components/resolver.ts +++ b/packages/components/resolver.ts @@ -34,6 +34,7 @@ const COMPONENT_NAMES = [ 'FaPasswordStrength', 'FaPopover', 'FaProgress', + 'FaRadioGroup', 'FaScrollArea', 'FaSearchBar', 'FaSelect', diff --git a/packages/components/src/radio-group/README.md b/packages/components/src/radio-group/README.md new file mode 100644 index 00000000..bf523345 --- /dev/null +++ b/packages/components/src/radio-group/README.md @@ -0,0 +1,226 @@ +# FaRadioGroup 单选组组件 + +基于选项数组的单选组件,支持描述文案、自定义布局样式和选项插槽扩展。 + +## 使用场景 + +- 表单中的单选配置项 +- 布局模式切换 +- 套餐、规格、主题方案选择 +- 带说明文案的单选列表 +- 需要自定义选项卡片样式的单选交互 + +## Props + +| 属性 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `options` | `RadioGroupOption[]` | **必需** | 单选组选项数据 | +| `disabled` | `boolean` | `false` | 是否整体禁用 | +| `orientation` | `'horizontal' \| 'vertical'` | `'vertical'` | 排列方向 | +| `dir` | `'ltr' \| 'rtl'` | - | 文本方向 | +| `class` | `HTMLAttributes['class']` | - | 单选组容器类名 | +| `optionClass` | `HTMLAttributes['class']` | - | 每个选项外层容器类名 | +| `itemClass` | `HTMLAttributes['class']` | - | `RadioGroupItem` 类名 | + +### RadioGroupOption 接口 + +```ts +interface RadioGroupOption { + label: string + value: AcceptableValue + description?: string + disabled?: boolean + id?: string +} +``` + +## Slots + +| 名称 | 说明 | +|------|------| +| `option` | 自定义选项内容,slot props: `{ option, checked, disabled, id }` | + +## Events + +| 事件名 | 说明 | 回调参数 | +|--------|------|----------| +| `change` | 选中值变化时触发 | `value: AcceptableValue \| undefined` | + +通过 `v-model` 实现双向绑定。 + +## 示例 + +### 基础用法 + +```vue + + + + + +``` + +### 带描述文案 + +```vue + + + + + +``` + +### 禁用状态 + +```vue + + + + + +``` + +### 横向排列 + +```vue + + + + + +``` + +### 自定义选项内容 + +```vue + + + + + + + + {{ option.label }} + + {{ option.description }} + + + + {{ checked ? '已选中' : '可选择' }} + + + + + +``` + +### 监听变化事件 + +```vue + + + + + +``` + +## 注意事项 + +1. **初始化值**:组件当前通过 `v-model` 管理选中值,不再提供 `defaultValue`。 +2. **选项结构**:`options` 至少需要 `label` 和 `value` 两个字段。 +3. **禁用优先级**:组件整体 `disabled` 为 `true` 时,会覆盖单项可用状态。 +4. **描述文案布局**:存在 `description` 时,选项会自动切换为顶部对齐布局。 +5. **自定义插槽**:使用 `option` 插槽后,默认 `RadioGroupItem` 会隐藏,需要由插槽内容自行承担完整视觉表现。 +6. **点击区域**:默认选项内容包裹在 `Label` 中,点击文字区域也能切换选中状态。 diff --git a/packages/components/src/radio-group/index.vue b/packages/components/src/radio-group/index.vue new file mode 100644 index 00000000..d7cc760c --- /dev/null +++ b/packages/components/src/radio-group/index.vue @@ -0,0 +1,131 @@ + + + + + + + + + + {{ option.label }} + + {{ option.description }} + + + + + + + diff --git a/packages/components/src/radio-group/radio-group/RadioGroup.vue b/packages/components/src/radio-group/radio-group/RadioGroup.vue new file mode 100644 index 00000000..af1ac4f5 --- /dev/null +++ b/packages/components/src/radio-group/radio-group/RadioGroup.vue @@ -0,0 +1,25 @@ + + + + + + + diff --git a/packages/components/src/radio-group/radio-group/RadioGroupItem.vue b/packages/components/src/radio-group/radio-group/RadioGroupItem.vue new file mode 100644 index 00000000..cbf41605 --- /dev/null +++ b/packages/components/src/radio-group/radio-group/RadioGroupItem.vue @@ -0,0 +1,40 @@ + + + + + + + + + + + diff --git a/packages/components/src/radio-group/radio-group/index.ts b/packages/components/src/radio-group/radio-group/index.ts new file mode 100644 index 00000000..fa1da9c2 --- /dev/null +++ b/packages/components/src/radio-group/radio-group/index.ts @@ -0,0 +1,2 @@ +export { default as RadioGroup } from './RadioGroup.vue' +export { default as RadioGroupItem } from './RadioGroupItem.vue'