Repository: element-plus/element-plus
File: packages/components/radio/src/radio-group.vue (Vue)

Code before:
import { radioGroupKey } from './constants'
import ElRadio from './radio.vue'

import type { RadioGroupProps } from './radio-group'

defineOptions({
  name: 'ElRadioGroup',
})

const props = defineProps(radioGroupProps)
const emit = defineEmits(radioGroupEmits)

const ns = useNamespace('radio')
const radioId = useId()
const radioGroupRef = ref<HTMLDivElement>()
const { formItem } = useFormItem()
const { inputId: groupId, isLabeledByFormItem } = useFormItemInputId(props, {
  formItemContext: formItem,
})

const changeEvent = (value: RadioGroupProps['modelValue']) => {
  emit(UPDATE_MODEL_EVENT, value)
  nextTick(() => emit(CHANGE_EVENT, value))
}

const { options = [], props: propConfig } = props
const valueKey = propConfig?.value ?? 'value'
const labelKey = propConfig?.label ?? 'label'
const disabledKey = propConfig?.disabled ?? 'disabled'
const radioOptions = computed(() => {
  return options.map((item) => ({
    value: item[valueKey],
    label: item[labelKey],
    disabled: item[disabledKey],
  }))
})

onMounted(() => {
  const radios =
    radioGroupRef.value!.querySelectorAll<HTMLInputElement>('[type=radio]')
  const firstLabel = radios[0]
  if (!Array.from(radios).some((radio) => radio.checked) && firstLabel) {
    firstLabel.tabIndex = 0
  }
})

const name = computed(() => {
  return props.name || radioId.value
})

provide(

Review comment (bug):
[bug](https://element-plus.run/#eyJBcHAudnVlIjoiPHRlbXBsYXRlPlxuICA8ZWwtcmFkaW8tZ3JvdXAgdi1tb2RlbD1cInJhZGlvXCIgOm9wdGlvbnM9XCJvcHRpb25zXCIgLz5cbjwvdGVtcGxhdGU+XG5cbjxzY3JpcHQgbGFuZz1cInRzXCIgc2V0dXA+XG5pbXBvcnQgeyByZWYgfSBmcm9tICd2dWUnXG5cbmNvbnN0IHJhZGlvID0gcmVmKDMpXG5cbmNvbnN0IG9wdGlvbnMgPSByZWYoW1xuICB7XG4gICAgdmFsdWU6IDMsXG4gICAgbGFiZWw6ICdPcHRpb24gQScsXG4gIH0sXG4gIHtcbiAgICB2YWx1ZTogNixcbiAgICBsYWJlbDogJ09wdGlvbiBCJyxcbiAgfSxcbiAge1xuICAgIHZhbHVlOiA5LFxuICAgIGxhYmVsOiAnT3B0aW9uIEMnLFxuICB9LFxuXSlcblxuc2V0VGltZW91dCgoKT0+e1xuICBvcHRpb25zLnZhbHVlID0gW3tcbiAgICB2YWx1ZTogOSxcbiAgICBsYWJlbDogJ09wdGlvbiBDJyxcbiAgfV1cbn0sMjAwMClcbjwvc2NyaXB0PlxuIiwiZWxlbWVudC1wbHVzLmpzIjoiaW1wb3J0IEVsZW1lbnRQbHVzIGZyb20gJ2VsZW1lbnQtcGx1cydcbmltcG9ydCB7IGdldEN1cnJlbnRJbnN0YW5jZSB9IGZyb20gJ3Z1ZSdcblxubGV0IGluc3RhbGxlZCA9IGZhbHNlXG5hd2FpdCBsb2FkU3R5bGUoKVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0dXBFbGVtZW50UGx1cygpIHtcbiAgaWYgKGluc3RhbGxlZCkgcmV0dXJuXG4gIGNvbnN0IGluc3RhbmNlID0gZ2V0Q3VycmVudEluc3RhbmNlKClcbiAgaW5zdGFuY2UuYXBwQ29udGV4dC5hcHAudXNlKEVsZW1lbnRQbHVzKVxuICBpbnN0YWxsZWQgPSB0cnVlXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBsb2FkU3R5bGUoKSB7XG4gIGNvbnN0IHN0eWxlcyA9IFsnaHR0cHM6Ly9wcmV2aWV3LTIxNTQzLWVsZW1lbnQtcGx1cy5zdXJnZS5zaC9idW5kbGUvZGlzdC9pbmRleC5jc3MnLCAnaHR0cHM6Ly9wcmV2aWV3LTIxNTQzLWVsZW1lbnQtcGx1cy5zdXJnZS5zaC9idW5kbGUvdGhlbWUtY2hhbGsvZGFyay9jc3MtdmFycy5jc3MnXS5tYXAoKHN0eWxlKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IGxpbmsgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsaW5rJylcbiAgICAgIGxpbmsucmVsID0gJ3N0eWxlc2hlZXQnXG4gICAgICBsaW5rLmhyZWYgPSBzdHlsZVxuICAgICAgbGluay5hZGRFdmVudExpc3RlbmVyKCdsb2FkJywgcmVzb2x2ZSlcbiAgICAgIGxpbmsuYWRkRXZlbnRMaXN0ZW5lcignZXJyb3InLCByZWplY3QpXG4gICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZChsaW5rKVxuICAgIH0pXG4gIH0pXG4gIHJldHVybiBQcm9taXNlLmFsbFNldHRsZWQoc3R5bGVzKVxufVxuIiwidHNjb25maWcuanNvbiI6IntcbiAgXCJjb21waWxlck9wdGlvbnNcIjoge1xuICAgIFwidGFyZ2V0XCI6IFwiRVNOZXh0XCIsXG4gICAgXCJqc3hcIjogXCJwcmVzZXJ2ZVwiLFxuICAgIFwibW9kdWxlXCI6IFwiRVNOZXh0XCIsXG4gICAgXCJtb2R1bGVSZXNvbHV0aW9uXCI6IFwiQnVuZGxlclwiLFxuICAgIFwidHlwZXNcIjogW1wiZWxlbWVudC1wbHVzL2dsb2JhbC5kLnRzXCJdLFxuICAgIFwiYWxsb3dJbXBvcnRpbmdUc0V4dGVuc2lvbnNcIjogdHJ1ZSxcbiAgICBcImFsbG93SnNcIjogdHJ1ZSxcbiAgICBcImNoZWNrSnNcIjogdHJ1ZVxuICB9LFxuICBcInZ1ZUNvbXBpbGVyT3B0aW9uc1wiOiB7XG4gICAgXCJ0YXJnZXRcIjogMy4zXG4gIH1cbn1cbiIsIlBsYXlncm91bmRNYWluLnZ1ZSI6IjxzY3JpcHQgc2V0dXA+XG5pbXBvcnQgQXBwIGZyb20gJy4vQXBwLnZ1ZSdcbmltcG9ydCB7IHNldHVwRWxlbWVudFBsdXMgfSBmcm9tICcuL2VsZW1lbnQtcGx1cy5qcydcbnNldHVwRWxlbWVudFBsdXMoKVxuPC9zY3JpcHQ+XG5cbjx0ZW1wbGF0ZT5cbiAgPEFwcCAvPlxuPC90ZW1wbGF0ZT5cbiIsImltcG9ydC1tYXAuanNvbiI6IntcbiAgXCJpbXBvcnRzXCI6IHtcbiAgICBcInZ1ZVwiOiBcImh0dHBzOi8vZmFzdGx5LmpzZGVsaXZyLm5ldC9ucG0vQHZ1ZS9ydW50aW1lLWRvbUBsYXRlc3QvZGlzdC9ydW50aW1lLWRvbS5lc20tYnJvd3Nlci5qc1wiLFxuICAgIFwiQHZ1ZS9zaGFyZWRcIjogXCJodHRwczovL2Zhc3RseS5qc2RlbGl2ci5uZXQvbnBtL0B2dWUvc2hhcmVkQGxhdGVzdC9kaXN0L3NoYXJlZC5lc20tYnVuZGxlci5qc1wiLFxuICAgIFwiZWxlbWVudC1wbHVzXCI6IFwiaHR0cHM6Ly9wcmV2aWV3LTIxNTQzLWVsZW1lbnQtcGx1cy5zdXJnZS5zaC9idW5kbGUvZGlzdC9pbmRleC5mdWxsLm1pbi5tanNcIixcbiAgICBcImVsZW1lbnQtcGx1cy9cIjogXCJ1bnN1cHBvcnRlZFwiLFxuICAgIFwiQGVsZW1lbnQtcGx1cy9pY29ucy12dWVcIjogXCJodHRwczovL2Zhc3RseS5qc2RlbGl2ci5uZXQvbnBtL0BlbGVtZW50LXBsdXMvaWNvbnMtdnVlQDIvZGlzdC9pbmRleC5taW4uanNcIlxuICB9LFxuICBcInNjb3Blc1wiOiB7fVxufSIsIl9vIjp7InNob3dIaWRkZW4iOnRydWUsInN0eWxlU291cmNlIjoiaHR0cHM6Ly9wcmV2aWV3LTIxNTQzLWVsZW1lbnQtcGx1cy5zdXJnZS5zaC9idW5kbGUvZGlzdC9pbmRleC5jc3MifX0=)

Code after:
  radioGroupProps,
} from './radio-group'
import { radioGroupKey } from './constants'
import { isEqual } from 'lodash-unified'
import ElRadio from './radio.vue'

import type { RadioGroupProps } from './radio-group'

defineOptions({
  name: 'ElRadioGroup',
})

const props = defineProps(radioGroupProps)
const emit = defineEmits(radioGroupEmits)

const ns = useNamespace('radio')
const radioId = useId()
const radioGroupRef = ref<HTMLDivElement>()
const { formItem } = useFormItem()
const { inputId: groupId, isLabeledByFormItem } = useFormItemInputId(props, {
  formItemContext: formItem,
})

const changeEvent = (value: RadioGroupProps['modelValue']) => {
  emit(UPDATE_MODEL_EVENT, value)
  nextTick(() => emit(CHANGE_EVENT, value))
}

onMounted(() => {
  const radios =
    radioGroupRef.value!.querySelectorAll<HTMLInputElement>('[type=radio]')
  const firstLabel = radios[0]
  if (!Array.from(radios).some((radio) => radio.checked) && firstLabel) {
    firstLabel.tabIndex = 0
  }
})

const name = computed(() => {
  return props.name || radioId.value
})

const aliasProps = computed(() => ({
  ...radioDefaultProps,
  ...props.props,
}))
const getOptionProps = (option: Record<string, any>) => {
  const base = {
    label: option[aliasProps.value.label],
    value: option[aliasProps.value.value],
    disabled: option[aliasProps.value.disabled],
  }