use-radio.ts 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. import { computed, inject, ref } from 'vue'
  2. import { UPDATE_MODEL_EVENT } from '@element-plus/constants'
  3. import { useFormDisabled, useFormSize } from '@element-plus/components/form'
  4. import { radioGroupKey } from './constants'
  5. import type { SetupContext } from 'vue'
  6. import type { RadioEmits, RadioProps } from './radio'
  7. export const useRadio = (
  8. props: { label: RadioProps['label']; modelValue?: RadioProps['modelValue'] },
  9. emit?: SetupContext<RadioEmits>['emit']
  10. ) => {
  11. const radioRef = ref<HTMLInputElement>()
  12. const radioGroup = inject(radioGroupKey, undefined)
  13. const isGroup = computed(() => !!radioGroup)
  14. const modelValue = computed<RadioProps['modelValue']>({
  15. get() {
  16. return isGroup.value ? radioGroup!.modelValue : props.modelValue!
  17. },
  18. set(val) {
  19. if (isGroup.value) {
  20. radioGroup!.changeEvent(val)
  21. } else {
  22. emit && emit(UPDATE_MODEL_EVENT, val)
  23. }
  24. radioRef.value!.checked = props.modelValue === props.label
  25. },
  26. })
  27. const size = useFormSize(computed(() => radioGroup?.size))
  28. const disabled = useFormDisabled(computed(() => radioGroup?.disabled))
  29. const focus = ref(false)
  30. const tabIndex = computed(() => {
  31. return disabled.value || (isGroup.value && modelValue.value !== props.label)
  32. ? -1
  33. : 0
  34. })
  35. return {
  36. radioRef,
  37. isGroup,
  38. radioGroup,
  39. focus,
  40. size,
  41. disabled,
  42. tabIndex,
  43. modelValue,
  44. }
  45. }