This commit is contained in:
oneao committed 2025-09-15 17:31:18 +08:00
1 parent ae0ad2bd63
commit 5a7e96db02
12 files changed
+466 -85

No files matched your search

+1
View File
@@ -10,6 +10,7 @@
},
"dependencies": {
"@ao/ao-design": "workspace:*",
"@arco-design/web-vue": "^2.57.0",
"@floating-ui/vue": "^1.1.9",
"@iconify/vue": "5.0.0",
"naive-ui": "^2.42.0",
@@ -6,7 +6,8 @@ export { default as Icon } from './icon'
export { default as Input } from './input'
export { default as Popconfirm } from './popconfirm'
export { default as Popup } from './popup'
export { default as Radio } from './radio'
export { default as Radio } from './radio/radio'
export { default as RadioGroup } from './radio/radio-group'
export { default as Separator } from './separator'
export { default as Space } from './space'
export { default as Spin } from './spin'
@@ -22,7 +22,17 @@
-webkit-box-sizing: border-box;
box-sizing: border-box;
font-family:
'Helvetica', 'Arial', 'PingFangSC-Regular', 'Hiragino Sans GB', 'Microsoft YaHei', '微软雅黑', 'Microsoft JhengHei';
Inter,
-apple-system,
BlinkMacSystemFont,
Segoe UI,
PingFang SC,
Hiragino Sans GB,
Microsoft YaHei,
Helvetica Neue,
Helvetica,
Arial,
sans-serif;
}
html,
@@ -1,7 +1,7 @@
import type { InjectionKey, Slots } from 'vue'
export interface RadioGroupContext {
name: 'ArcoRadioGroup'
name: 'AoRadioGroup'
value: string | number | boolean
disabled: boolean
slots: Slots
@@ -1,6 +1,7 @@
@use '../_styles/_variables.scss' as *;
$radio-prefix: '#{$prefix}-radio';
$radio-group-prefix: '#{$prefix}-radio-group';
.#{$radio-prefix} {
color: $text-color-base;
@@ -10,6 +11,11 @@ $radio-prefix: '#{$prefix}-radio';
cursor: pointer;
user-select: none;
&.#{$radio-prefix}-disabled {
cursor: not-allowed;
opacity: 0.5;
}
&:hover .#{$radio-prefix}-main .#{$radio-prefix}-inner {
border-color: $primary-color;
}
@@ -42,8 +48,8 @@ $radio-prefix: '#{$prefix}-radio';
.#{$radio-prefix}-inner {
border: 1px solid $border-color;
border-radius: 100%;
width: 16px;
height: 16px;
width: 14px;
height: 14px;
background-color: $bg-color-container;
position: relative;
display: inline-block;
@@ -52,8 +58,8 @@ $radio-prefix: '#{$prefix}-radio';
outline: 0;
&::after {
box-sizing: border-box;
width: 8px;
height: 8px;
width: 6px;
height: 6px;
border-radius: 999px;
background-color: transparent;
content: '';
@@ -62,8 +68,8 @@ $radio-prefix: '#{$prefix}-radio';
top: 50%;
transform: translate(-50%, -50%) scale(0);
transition:
transform 0.15s ease-in,
background-color 0.15s ease-in;
transform 0.1s ease-in,
background-color 0.1s ease-in;
}
}
}
@@ -72,6 +78,8 @@ $radio-prefix: '#{$prefix}-radio';
font-size: 12px;
margin-left: 8px;
vertical-align: middle;
line-height: 1;
}
}
.#{$radio-group-prefix} {
}
@@ -1,70 +0,0 @@
import { defineComponent, inject } from 'vue'
import { getPrefixCls } from '../_utils/getPrefixCls'
import { radioGroupKey } from './context'
export default defineComponent({
name: 'Radio',
props: {
checked: {
type: Boolean,
default: false,
},
value: {
type: [String, Number],
required: false,
},
disabled: {
type: Boolean,
default: false,
},
// private
uninjectGroupContext: {
type: Boolean,
default: false,
},
},
emits: ['change', 'update:checked'],
setup(props, { slots, emit }) {
const prefixCls = getPrefixCls('radio')
const radioGroupCtx = !props.uninjectGroupContext
? inject(radioGroupKey, undefined)
: undefined
const handleClick = () => {
if (props.disabled)
return
const newChecked = !props.checked
emit('update:checked', newChecked)
emit('change', {
value: props.value,
checked: newChecked,
})
}
return () => (
<label
class={[
prefixCls,
props.checked ? `${prefixCls}-checked` : '',
props.disabled ? `${prefixCls}-disabled` : '',
]}
onClick={handleClick}
>
<span class={`${prefixCls}-main`}>
<span class={`${prefixCls}-inner`} />
<input
class={`${prefixCls}-input`}
type="radio"
checked={props.checked}
disabled={props.disabled}
onClick={e => e.stopPropagation()}
/>
</span>
<span class={`${prefixCls}-content`}>
{slots.default ? slots.default() : null}
</span>
</label>
)
},
})
@@ -0,0 +1,112 @@
import type { PropType, RenderFunction } from 'vue'
import { computed, defineComponent, provide, reactive, ref, watch } from 'vue'
import { getPrefixCls } from '../_utils/getPrefixCls'
import Space from '../space/index'
import { radioGroupKey } from './context'
import Radio from './radio'
interface RadioOption {
label?: string | RenderFunction
value?: string | number
extra?: string | RenderFunction
disabled?: boolean
[key: string]: any
}
export default defineComponent({
name: 'RadioGroup',
props: {
modelValue: {
type: [String, Number, Boolean] as PropType<string | number | boolean>,
default: undefined,
},
defaultValue: {
type: [String, Number, Boolean] as PropType<string | number | boolean>,
default: '',
},
disabled: {
type: Boolean,
default: false,
},
labelField: {
type: String,
default: 'label',
},
valueField: {
type: String,
default: 'value',
},
options: {
type: Array as PropType<Array<string | number | RadioOption>>,
default: [],
},
spaceProps: {
type: Object as PropType<Record<string, any>>,
default: () => ({}),
},
},
emits: ['update:modelValue', 'change'],
setup(props, { emit, slots }) {
const prefixCls = getPrefixCls('radio-group')
// 内部值,优先使用 v-model
const _value = ref(props.modelValue ?? props.defaultValue)
watch(() => props.modelValue, (newVal) => {
if (newVal !== undefined) {
_value.value = newVal
}
})
const handleChange = (val: string | number | boolean, e: Event) => {
_value.value = val
emit('update:modelValue', val)
emit('change', val, e)
}
const groupDisabled = computed(() => props.disabled)
// 提供 context 给 Radio 使用
provide(radioGroupKey, reactive({
name: 'AoRadioGroup' as const,
value: _value,
disabled: groupDisabled,
slots,
handleChange,
}))
const renderOptions = () => {
return props.options.map((option) => {
// 标准化 option
const opt: RadioOption
= typeof option === 'string' || typeof option === 'number'
? { [props.labelField]: String(option), [props.valueField]: option }
: option
const labelContent = slots.label
? slots.label({ data: opt })
: typeof opt[props.labelField] === 'function'
? opt[props.labelField]()
: opt[props.labelField]
return (
<Radio
key={opt[props.valueField]}
value={opt[props.valueField]}
disabled={opt.disabled ?? props.disabled}
modelValue={_value.value === opt[props.valueField]}
>
{labelContent}
</Radio>
)
})
}
return () => (
<div class={[prefixCls]}>
<Space {...props.spaceProps}>
{props.options.length > 0 ? renderOptions() : slots.default?.()}
</Space>
</div>
)
},
})
@@ -0,0 +1,96 @@
import type { PropType, VNode } from 'vue'
import type { RadioGroupContext } from './context'
import { computed, defineComponent, inject, ref } from 'vue'
import { getPrefixCls } from '../_utils/getPrefixCls'
import { radioGroupKey } from './context'
export default defineComponent({
name: 'Radio',
props: {
modelValue: {
type: Boolean,
default: undefined,
},
defaultChecked: {
type: Boolean,
default: false,
},
disabled: {
type: Boolean,
default: false,
},
value: {
type: [String, Number, Boolean] as PropType<string | number | boolean>,
default: true,
},
allowUncheck: {
type: Boolean,
default: true,
},
extra: {
type: [String, Object, Function] as unknown as () => string | VNode | (() => VNode),
default: '',
},
},
emits: ['update:modelValue', 'change'],
setup(props, { slots, emit }) {
const prefixCls = getPrefixCls('radio')
const radioGroupCtx = inject<RadioGroupContext | undefined>(radioGroupKey, undefined)
const inGroup = computed(() => !!radioGroupCtx)
const isDisabled = computed(() => props.disabled || radioGroupCtx?.disabled)
const _checked = ref(props.defaultChecked)
// 判断是否选中
const isChecked = computed(() => {
if (inGroup.value)
return props.value === radioGroupCtx!.value
return _checked.value
})
const handleClick = (e: Event) => {
if (isDisabled.value)
return
if (isChecked.value && !props.allowUncheck)
return
if (inGroup.value) {
const newValue = isChecked.value && props.allowUncheck ? '' : props.value
radioGroupCtx?.handleChange(newValue, e)
}
else {
const newValue = props.allowUncheck ? !isChecked.value : true
_checked.value = newValue
emit('update:modelValue', newValue)
emit('change', props.value, e)
}
}
return () => (
<label
class={[
prefixCls,
isDisabled.value ? `${prefixCls}-disabled` : '',
isChecked.value ? `${prefixCls}-checked` : '',
]}
onClick={handleClick}
>
<span class={`${prefixCls}-main`}>
<span class={`${prefixCls}-inner`} />
<input
class={`${prefixCls}-input`}
type="radio"
disabled={isDisabled.value}
onClick={e => e.stopPropagation()}
/>
</span>
<span class={`${prefixCls}-content`}>
{slots.default?.()}
</span>
</label>
)
},
})
+116
View File
@@ -11,6 +11,9 @@ importers:
'@ao/ao-design':
specifier: workspace:*
version: link:packages/ao-design
'@arco-design/web-vue':
specifier: ^2.57.0
version: 2.57.0(vue@3.5.19(typescript@5.8.3))
'@floating-ui/vue':
specifier: ^1.1.9
version: 1.1.9(vue@3.5.19(typescript@5.8.3))
@@ -153,6 +156,14 @@ packages:
'@antfu/install-pkg@1.1.0':
resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==}
'@arco-design/color@0.4.0':
resolution: {integrity: sha512-s7p9MSwJgHeL8DwcATaXvWT3m2SigKpxx4JA1BGPHL4gfvaQsmQfrLBDpjOJFJuJ2jG2dMt3R3P8Pm9E65q18g==}
'@arco-design/web-vue@2.57.0':
resolution: {integrity: sha512-R5YReC3C2sG3Jv0+YuR3B7kzkq2KdhhQNCGXD8T11xAoa0zMt6SWTP1xJQOdZcM9du+q3z6tk5mRvh4qkieRJw==}
peerDependencies:
vue: ^3.1.0
'@babel/code-frame@7.27.1':
resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==}
engines: {node: '>=6.9.0'}
@@ -623,36 +634,42 @@ packages:
engines: {node: '>= 10.0.0'}
cpu: [arm]
os: [linux]
libc: [glibc]
'@parcel/watcher-linux-arm-musl@2.5.1':
resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==}
engines: {node: '>= 10.0.0'}
cpu: [arm]
os: [linux]
libc: [musl]
'@parcel/watcher-linux-arm64-glibc@2.5.1':
resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@parcel/watcher-linux-arm64-musl@2.5.1':
resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==}
engines: {node: '>= 10.0.0'}
cpu: [arm64]
os: [linux]
libc: [musl]
'@parcel/watcher-linux-x64-glibc@2.5.1':
resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [linux]
libc: [glibc]
'@parcel/watcher-linux-x64-musl@2.5.1':
resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==}
engines: {node: '>= 10.0.0'}
cpu: [x64]
os: [linux]
libc: [musl]
'@parcel/watcher-win32-arm64@2.5.1':
resolution: {integrity: sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==}
@@ -727,56 +744,67 @@ packages:
resolution: {integrity: sha512-JWnrj8qZgLWRNHr7NbpdnrQ8kcg09EBBq8jVOjmtlB3c8C6IrynAJSMhMVGME4YfTJzIkJqvSUSVJRqkDnu/aA==}
cpu: [arm]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-arm-musleabihf@4.48.0':
resolution: {integrity: sha512-9xu92F0TxuMH0tD6tG3+GtngwdgSf8Bnz+YcsPG91/r5Vgh5LNofO48jV55priA95p3c92FLmPM7CvsVlnSbGQ==}
cpu: [arm]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-arm64-gnu@4.48.0':
resolution: {integrity: sha512-NLtvJB5YpWn7jlp1rJiY0s+G1Z1IVmkDuiywiqUhh96MIraC0n7XQc2SZ1CZz14shqkM+XN2UrfIo7JB6UufOA==}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-arm64-musl@4.48.0':
resolution: {integrity: sha512-QJ4hCOnz2SXgCh+HmpvZkM+0NSGcZACyYS8DGbWn2PbmA0e5xUk4bIP8eqJyNXLtyB4gZ3/XyvKtQ1IFH671vQ==}
cpu: [arm64]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-loongarch64-gnu@4.48.0':
resolution: {integrity: sha512-Pk0qlGJnhILdIC5zSKQnprFjrGmjfDM7TPZ0FKJxRkoo+kgMRAg4ps1VlTZf8u2vohSicLg7NP+cA5qE96PaFg==}
cpu: [loong64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-ppc64-gnu@4.48.0':
resolution: {integrity: sha512-/dNFc6rTpoOzgp5GKoYjT6uLo8okR/Chi2ECOmCZiS4oqh3mc95pThWma7Bgyk6/WTEvjDINpiBCuecPLOgBLQ==}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-riscv64-gnu@4.48.0':
resolution: {integrity: sha512-YBwXsvsFI8CVA4ej+bJF2d9uAeIiSkqKSPQNn0Wyh4eMDY4wxuSp71BauPjQNCKK2tD2/ksJ7uhJ8X/PVY9bHQ==}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-riscv64-musl@4.48.0':
resolution: {integrity: sha512-FI3Rr2aGAtl1aHzbkBIamsQyuauYtTF9SDUJ8n2wMXuuxwchC3QkumZa1TEXYIv/1AUp1a25Kwy6ONArvnyeVQ==}
cpu: [riscv64]
os: [linux]
libc: [musl]
'@rollup/rollup-linux-s390x-gnu@4.48.0':
resolution: {integrity: sha512-Dx7qH0/rvNNFmCcIRe1pyQ9/H0XO4v/f0SDoafwRYwc2J7bJZ5N4CHL/cdjamISZ5Cgnon6iazAVRFlxSoHQnQ==}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-x64-gnu@4.48.0':
resolution: {integrity: sha512-GUdZKTeKBq9WmEBzvFYuC88yk26vT66lQV8D5+9TgkfbewhLaTHRNATyzpQwwbHIfJvDJ3N9WJ90wK/uR3cy3Q==}
cpu: [x64]
os: [linux]
libc: [glibc]
'@rollup/rollup-linux-x64-musl@4.48.0':
resolution: {integrity: sha512-ao58Adz/v14MWpQgYAb4a4h3fdw73DrDGtaiF7Opds5wNyEQwtO6M9dBh89nke0yoZzzaegq6J/EXs7eBebG8A==}
cpu: [x64]
os: [linux]
libc: [musl]
'@rollup/rollup-win32-arm64-msvc@4.48.0':
resolution: {integrity: sha512-kpFno46bHtjZVdRIOxqaGeiABiToo2J+st7Yce+aiAoo1H0xPi2keyQIP04n2JjDVuxBN6bSz9R6RdTK5hIppw==}
@@ -1037,6 +1065,12 @@ packages:
async-validator@4.2.5:
resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==}
b-tween@0.3.3:
resolution: {integrity: sha512-oEHegcRpA7fAuc9KC4nktucuZn2aS8htymCPcP3qkEGPqiBH+GfqtqoG2l7LxHngg6O0HFM7hOeOYExl1Oz4ZA==}
b-validate@1.5.3:
resolution: {integrity: sha512-iCvCkGFskbaYtfQ0a3GmcQCHl/Sv1GufXFGuUQ+FE+WJa7A/espLOuFIn09B944V8/ImPj71T4+rTASxO2PAuA==}
balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
@@ -1106,17 +1140,32 @@ packages:
resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==}
engines: {node: '>=4'}
color-convert@1.9.3:
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
color-convert@2.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
engines: {node: '>=7.0.0'}
color-name@1.1.3:
resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
color-string@1.9.1:
resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
color@3.2.1:
resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==}
comment-parser@1.4.1:
resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==}
engines: {node: '>= 12.0.0'}
compute-scroll-into-view@1.0.20:
resolution: {integrity: sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==}
concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
@@ -1596,6 +1645,9 @@ packages:
resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==}
engines: {node: '>=12'}
is-arrayish@0.3.4:
resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==}
is-binary-path@2.1.0:
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
engines: {node: '>=8'}
@@ -1907,6 +1959,9 @@ packages:
nth-check@2.1.1:
resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
number-precision@1.6.0:
resolution: {integrity: sha512-05OLPgbgmnixJw+VvEh18yNPUo3iyp4BEWJcrLu4X9W05KmMifN7Mu5exYvQXqxxeNWhvIF+j3Rij+HmddM/hQ==}
optionator@0.9.4:
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
engines: {node: '>= 0.8.0'}
@@ -2040,6 +2095,9 @@ packages:
resolution: {integrity: sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==}
hasBin: true
resize-observer-polyfill@1.5.1:
resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==}
resolve-from@4.0.0:
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
engines: {node: '>=4'}
@@ -2070,6 +2128,9 @@ packages:
sax@1.4.1:
resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==}
scroll-into-view-if-needed@2.2.31:
resolution: {integrity: sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==}
scslre@0.3.0:
resolution: {integrity: sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==}
engines: {node: ^14.0.0 || >=16.0.0}
@@ -2101,6 +2162,9 @@ packages:
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
engines: {node: '>=8'}
simple-swizzle@0.2.4:
resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==}
sisteransi@1.0.5:
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
@@ -2470,6 +2534,22 @@ snapshots:
package-manager-detector: 1.3.0
tinyexec: 1.0.1
'@arco-design/color@0.4.0':
dependencies:
color: 3.2.1
'@arco-design/web-vue@2.57.0(vue@3.5.19(typescript@5.8.3))':
dependencies:
'@arco-design/color': 0.4.0
b-tween: 0.3.3
b-validate: 1.5.3
compute-scroll-into-view: 1.0.20
dayjs: 1.11.18
number-precision: 1.6.0
resize-observer-polyfill: 1.5.1
scroll-into-view-if-needed: 2.2.31
vue: 3.5.19(typescript@5.8.3)
'@babel/code-frame@7.27.1':
dependencies:
'@babel/helper-validator-identifier': 7.27.1
@@ -3346,6 +3426,10 @@ snapshots:
async-validator@4.2.5: {}
b-tween@0.3.3: {}
b-validate@1.5.3: {}
balanced-match@1.0.2: {}
binary-extensions@2.3.0: {}
@@ -3413,14 +3497,32 @@ snapshots:
dependencies:
escape-string-regexp: 1.0.5
color-convert@1.9.3:
dependencies:
color-name: 1.1.3
color-convert@2.0.1:
dependencies:
color-name: 1.1.4
color-name@1.1.3: {}
color-name@1.1.4: {}
color-string@1.9.1:
dependencies:
color-name: 1.1.4
simple-swizzle: 0.2.4
color@3.2.1:
dependencies:
color-convert: 1.9.3
color-string: 1.9.1
comment-parser@1.4.1: {}
compute-scroll-into-view@1.0.20: {}
concat-map@0.0.1: {}
confbox@0.1.8: {}
@@ -3948,6 +4050,8 @@ snapshots:
indent-string@5.0.0: {}
is-arrayish@0.3.4: {}
is-binary-path@2.1.0:
dependencies:
binary-extensions: 2.3.0
@@ -4448,6 +4552,8 @@ snapshots:
dependencies:
boolbase: 1.0.0
number-precision@1.6.0: {}
optionator@0.9.4:
dependencies:
deep-is: 0.1.4
@@ -4566,6 +4672,8 @@ snapshots:
dependencies:
jsesc: 3.0.2
resize-observer-polyfill@1.5.1: {}
resolve-from@4.0.0: {}
resolve-pkg-maps@1.0.0: {}
@@ -4616,6 +4724,10 @@ snapshots:
sax@1.4.1:
optional: true
scroll-into-view-if-needed@2.2.31:
dependencies:
compute-scroll-into-view: 1.0.20
scslre@0.3.0:
dependencies:
'@eslint-community/regexpp': 4.12.1
@@ -4639,6 +4751,10 @@ snapshots:
shebang-regex@3.0.0: {}
simple-swizzle@0.2.4:
dependencies:
is-arrayish: 0.3.4
sisteransi@1.0.5: {}
sortablejs@1.15.6: {}
+104 -4
View File
@@ -1,10 +1,110 @@
<script setup lang="ts">
import { ref } from 'vue'
// Group 示例 1: 基本使用 + v-model
const selectedValue = ref('B')
// Group 示例 2: options 数组渲染
const options = [
{ label: 'XXX', value: 'X' },
{ label: '选项 Y', value: 'Y' },
{ label: '选项 Z', value: 'Z' },
]
// 单独 Radio 使用
const singleChecked = ref(false)
// Group Disabled
const groupDisabled = ref(false)
function toggleGroupDisabled() {
groupDisabled.value = !groupDisabled.value
console.log(groupDisabled.value);
}
function handleChange(val) {
console.log('选中值:', val)
}
</script>
<template>
<div style="height: 800px;display: flex;align-items: center;justify-content: center;">
<ARadio :checked="true">
选项一
</ARadio>
<div class="demo-wrapper">
<div class="demo-container">
<h3>ARadioGroup - 基本使用</h3>
<ARadioGroup
v-model="selectedValue"
default-value="B"
:disabled="groupDisabled"
class="demo-radio-group"
>
<ARadio value="A" extra="额外信息">选项 A</ARadio>
<ARadio value="B" >选项 B</ARadio>
<ARadio value="C">选项 C</ARadio>
</ARadioGroup>
<p>当前选中: {{ selectedValue }}</p>
<button @click="toggleGroupDisabled" class="demo-btn">
切换 Group Disabled
</button>
<h3>ARadioGroup - 使用 options 数组渲染</h3>
<ARadioGroup
v-model="selectedValue"
:options="options"
@change="handleChange"
class="demo-radio-group"
/>
<p>当前选中: {{ selectedValue }}</p>
<h3>单独 ARadio 使用</h3>
<ARadio v-model="singleChecked" value="X" :allow-uncheck="true">
单选 X
</ARadio>
<p>是否选中: {{ singleChecked }}</p>
</div>
</div>
</template>
<style scoped>
.demo-wrapper {
display: flex;
justify-content: center;
align-items: flex-start;
padding: 40px 16px;
}
.demo-container {
display: flex;
flex-direction: column;
gap: 24px; /* 各部分垂直间距 */
width: 100%;
max-width: 600px; /* 页面居中显示 */
background-color: #fff;
padding: 24px;
border-radius: 8px;
box-shadow: 0 2px 12px rgba(0,0,0,0.08);
}
.demo-radio-group {
display: flex;
gap: 16px;
margin-bottom: 8px;
}
.demo-btn {
padding: 6px 16px;
border: 1px solid #409eff;
background-color: #fff;
color: #409eff;
border-radius: 4px;
cursor: pointer;
transition: 0.2s;
}
.demo-btn:hover {
background-color: #409eff;
color: #fff;
}
</style>
+3
View File
@@ -19,6 +19,9 @@ declare module 'vue' {
APopconfirm: typeof import('@ao/ao-design')['Popconfirm']
APopup: typeof import('@ao/ao-design')['Popup']
ARadio: typeof import('@ao/ao-design')['Radio']
ARadioGroup: typeof import('@ao/ao-design')['RadioGroup']
ArcoRadio: typeof import('@ao/ao-design')['rcoRadio']
ArcoRadioGroup: typeof import('@ao/ao-design')['rcoRadioGroup']
ARdio: typeof import('@ao/ao-design')['Rdio']
ASeparator: typeof import('@ao/ao-design')['Separator']
ASpace: typeof import('@ao/ao-design')['Space']
+5 -1
View File
@@ -1,3 +1,4 @@
import ArcoVue from '@arco-design/web-vue'
import naive from 'naive-ui'
import TDesign from 'tdesign-vue-next'
import { createApp } from 'vue'
@@ -5,5 +6,8 @@ import App from './App.vue'
import './style.scss'
import 'tdesign-vue-next/es/style/index.css'
import '@arco-design/web-vue/dist/arco.css'
createApp(App).use(naive).use(TDesign).mount('#app')
createApp(App).use(naive).use(ArcoVue, {
componentPrefix: 'b',
}).use(TDesign).mount('#app')