Skip to content

Commit 9726d10

Browse files
author
issayah
committed
BFormRadio script setup conversion and fixes
1 parent 6e8b041 commit 9726d10

File tree

3 files changed

+161
-135
lines changed

3 files changed

+161
-135
lines changed

src/components/BFormRadio/BFormRadio.vue

Lines changed: 78 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88
:class="inputClasses"
99
type="radio"
1010
:disabled="disabled"
11-
:required="name && required"
11+
:required="!!name && !!required"
1212
:name="name"
1313
:form="form"
1414
:aria-label="ariaLabel"
1515
:aria-labelledby="ariaLabelledBy"
1616
:value="value"
17-
:aria-required="name && required ? 'true' : null"
17+
:aria-required="name && required ? true : undefined"
1818
@focus="isFocused = true"
1919
@blur="isFocused = false"
2020
/>
@@ -28,77 +28,88 @@
2828
</div>
2929
</template>
3030

31-
<script lang="ts">
32-
import {getClasses, getInputClasses, getLabelClasses} from '../../composables/useFormCheck'
33-
import {computed, defineComponent, onMounted, PropType, Ref, ref} from 'vue'
34-
import useId from '../../composables/useId'
31+
<script setup lang="ts">
32+
// import type {BFormRadioEmits, BFormRadioProps} from '@/types/components'
33+
import type {ButtonVariant} from '@/types'
34+
import {getClasses, getInputClasses, getLabelClasses} from '@/composables/useFormCheck'
35+
import {computed, onMounted, ref} from 'vue'
36+
import useId from '@/composables/useId'
3537
36-
export default defineComponent({
37-
name: 'BFormRadio',
38-
props: {
39-
ariaLabel: {type: String},
40-
ariaLabelledBy: {type: String},
41-
autofocus: {type: Boolean, default: false},
42-
modelValue: {type: [Boolean, String, Array, Object, Number], default: null},
43-
plain: {type: Boolean, default: false},
44-
button: {type: Boolean, default: false},
45-
switch: {type: Boolean, default: false},
46-
disabled: {type: Boolean, default: false},
47-
buttonVariant: {type: String, default: 'secondary'},
48-
form: {type: String},
49-
id: {type: String},
50-
inline: {type: Boolean, default: false},
51-
name: {type: String},
52-
required: {type: Boolean, default: false},
53-
size: {type: String},
54-
state: {type: Boolean as PropType<boolean | null | undefined>, default: null},
55-
value: {type: [String, Boolean, Object, Number], default: true},
56-
},
57-
emits: ['update:modelValue', 'change', 'input'],
58-
setup(props, {emit}) {
59-
const computedId = useId(props.id, 'form-check')
60-
const input: Ref<HTMLElement> = ref(null as unknown as HTMLElement)
61-
const isFocused = ref(false)
38+
interface BFormRadioProps {
39+
ariaLabel?: string
40+
ariaLabelledBy?: string
41+
form?: string
42+
id?: string
43+
name?: string
44+
size?: string
45+
autofocus?: boolean
46+
modelValue?: boolean | string | Array<unknown> | Record<string, unknown> | number
47+
plain?: boolean
48+
button?: boolean
49+
switch?: boolean
50+
disabled?: boolean
51+
buttonVariant?: ButtonVariant
52+
inline?: boolean
53+
required?: boolean
54+
state?: boolean | null
55+
value?: string | boolean | Record<string, unknown> | number
56+
}
6257
63-
const localValue: any = computed({
64-
get: () => (Array.isArray(props.modelValue) ? props.modelValue[0] : props.modelValue),
65-
set: (newValue: any) => {
66-
const value = newValue ? props.value : false
67-
const emitValue = Array.isArray(props.modelValue) ? [value] : value
68-
emit('input', emitValue)
69-
emit('change', emitValue)
70-
emit('update:modelValue', emitValue)
71-
},
72-
})
58+
const props = withDefaults(defineProps<BFormRadioProps>(), {
59+
autofocus: false,
60+
modelValue: undefined,
61+
plain: false,
62+
button: false,
63+
switch: false,
64+
disabled: false,
65+
buttonVariant: 'secondary',
66+
inline: false,
67+
required: false,
68+
state: undefined,
69+
value: true,
70+
})
7371
74-
const isChecked = computed(() => {
75-
if (Array.isArray(props.modelValue)) {
76-
return (props.modelValue || []).find((e) => e === props.value)
77-
}
78-
return JSON.stringify(props.modelValue) === JSON.stringify(props.value)
79-
})
72+
interface BFormRadioEmits {
73+
(e: 'input', value: boolean | string | Array<unknown> | Record<string, unknown> | number): void
74+
(e: 'change', value: boolean | string | Array<unknown> | Record<string, unknown> | number): void
75+
(
76+
e: 'update:modelValue',
77+
value: boolean | string | Array<unknown> | Record<string, unknown> | number
78+
): void
79+
}
8080
81-
const classes = getClasses(props)
82-
const inputClasses = getInputClasses(props)
83-
const labelClasses = getLabelClasses(props)
81+
const emit = defineEmits<BFormRadioEmits>()
8482
85-
// TODO: make tests compatible with the v-focus directive
86-
if (props.autofocus) {
87-
onMounted(() => {
88-
input.value.focus()
89-
})
90-
}
83+
const computedId = useId(props.id, 'form-check')
84+
const input = ref<HTMLElement>(null as unknown as HTMLElement)
85+
const isFocused = ref<boolean>(false)
9186
92-
return {
93-
localValue,
94-
computedId,
95-
classes,
96-
inputClasses,
97-
labelClasses,
98-
isChecked,
99-
isFocused,
100-
input,
101-
}
87+
const localValue = computed<unknown>({
88+
get: () => (Array.isArray(props.modelValue) ? props.modelValue[0] : props.modelValue),
89+
set: (newValue: any) => {
90+
const value = newValue ? props.value : false
91+
const emitValue = Array.isArray(props.modelValue) ? [value] : value
92+
emit('input', emitValue)
93+
emit('change', emitValue)
94+
emit('update:modelValue', emitValue)
10295
},
10396
})
97+
98+
const isChecked = computed<unknown>(() => {
99+
if (Array.isArray(props.modelValue)) {
100+
return (props.modelValue || []).find((e) => e === props.value)
101+
}
102+
return JSON.stringify(props.modelValue) === JSON.stringify(props.value)
103+
})
104+
105+
const classes = getClasses(props)
106+
const inputClasses = getInputClasses(props)
107+
const labelClasses = getLabelClasses(props)
108+
109+
// TODO: make tests compatible with the v-focus directive
110+
onMounted(() => {
111+
if (props.autofocus) {
112+
input.value.focus()
113+
}
114+
})
104115
</script>

src/components/BFormRadio/BFormRadioGroup.vue

Lines changed: 78 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -18,81 +18,97 @@
1818
</div>
1919
</template>
2020

21-
<script lang="ts">
22-
import {computed, defineComponent, PropType} from 'vue'
21+
<script setup lang="ts">
22+
// import type {BFormRadioGroupEmits, BFormRadioGroupProps} from '@/types/components'
23+
import type {ButtonVariant, Size} from '@/types'
24+
import {computed, useSlots} from 'vue'
2325
import BFormRadio from './BFormRadio.vue'
24-
import {ColorVariant, Size} from '../../types'
2526
import {
2627
bindGroupProps,
2728
getGroupAttr,
2829
getGroupClasses,
2930
optionToElement,
3031
slotsToElements,
31-
} from '../../composables/useFormCheck'
32-
import useId from '../../composables/useId'
32+
} from '@/composables/useFormCheck'
33+
import useId from '@/composables/useId'
3334
34-
export default defineComponent({
35-
name: 'BFormRadioGroup',
36-
components: {BFormRadio},
37-
props: {
38-
modelValue: {type: [String, Boolean, Array, Object, Number], default: ''},
39-
ariaInvalid: {type: [Boolean, String], default: null},
40-
autofocus: {type: Boolean, default: false},
41-
buttonVariant: {type: String as PropType<ColorVariant>, default: 'secondary'},
42-
buttons: {type: Boolean, default: false},
43-
disabled: {type: Boolean, default: false},
44-
disabledField: {type: String, default: 'disabled'},
45-
form: {type: String},
46-
htmlField: {type: String, default: 'html'},
47-
id: {type: String},
48-
name: {type: String},
49-
options: {type: Array, default: () => []}, // Objects are not supported yet
50-
plain: {type: Boolean, default: false},
51-
required: {type: Boolean, default: false},
52-
size: {type: String as PropType<Size>},
53-
stacked: {type: Boolean, default: false},
54-
state: {type: Boolean, default: null},
55-
textField: {type: String, default: 'text'},
56-
validated: {type: Boolean, default: false},
57-
valueField: {type: String, default: 'value'},
58-
},
59-
emits: ['update:modelValue', 'input', 'change'],
60-
setup(props, {emit, slots}) {
61-
const slotsName = 'BFormRadio'
62-
const computedId = useId(props.id, 'radio')
63-
const computedName = useId(props.name, 'checkbox')
35+
interface BFormRadioGroupProps {
36+
size?: Size
37+
form?: string
38+
id?: string
39+
name?: string
40+
modelValue?: string | boolean | Array<unknown> | Record<string, unknown> | number
41+
ariaInvalid?: boolean | string
42+
autofocus?: boolean
43+
buttonVariant?: ButtonVariant
44+
buttons?: boolean
45+
disabled?: boolean
46+
disabledField?: string
47+
htmlField?: string
48+
options?: Array<unknown> // Objects are not supported yet
49+
plain?: boolean
50+
required?: boolean
51+
stacked?: boolean
52+
state?: boolean
53+
textField?: string
54+
validated?: boolean
55+
valueField?: string
56+
}
57+
58+
const props = withDefaults(defineProps<BFormRadioGroupProps>(), {
59+
modelValue: '',
60+
ariaInvalid: undefined,
61+
autofocus: false,
62+
buttonVariant: 'secondary',
63+
buttons: false,
64+
disabled: false,
65+
disabledField: 'disabled',
66+
htmlField: 'html',
67+
options: () => [],
68+
plain: false,
69+
required: false,
70+
stacked: false,
71+
state: undefined,
72+
textField: 'text',
73+
validated: false,
74+
valueField: 'value',
75+
})
6476
65-
const localValue = computed({
66-
get: () => props.modelValue,
67-
set: (newValue: any) => {
68-
emit('input', newValue)
69-
emit('update:modelValue', newValue)
70-
emit('change', newValue)
71-
},
72-
})
77+
interface BFormRadioGroupEmits {
78+
(e: 'input', value: unknown): void
79+
(e: 'update:modelValue', value: unknown): void
80+
(e: 'change', value: unknown): void
81+
}
7382
74-
const checkboxList = computed(() =>
75-
(slots.first ? slotsToElements(slots.first(), slotsName, props.disabled) : [])
76-
.concat(props.options.map((e) => optionToElement(e, props)))
77-
.concat(slots.default ? slotsToElements(slots.default(), slotsName, props.disabled) : [])
78-
.map((e, idx) => bindGroupProps(e, idx, props, computedName, computedId))
79-
.map((e) => ({
80-
...e,
81-
}))
82-
)
83+
const emit = defineEmits<BFormRadioGroupEmits>()
8384
84-
const attrs = getGroupAttr(props)
85-
const classes = getGroupClasses(props)
85+
const slots = useSlots()
8686
87-
// TODO: make tests compatible with the v-focus directive
87+
const slotsName = 'BFormRadio'
88+
const computedId = useId(props.id, 'radio')
89+
const computedName = useId(props.name, 'checkbox')
8890
89-
return {
90-
attrs,
91-
classes,
92-
checkboxList,
93-
computedId,
94-
localValue,
95-
}
91+
const localValue = computed<string | boolean | Array<unknown> | Record<string, unknown> | number>({
92+
get: () => props.modelValue,
93+
set: (newValue: any) => {
94+
emit('input', newValue)
95+
emit('update:modelValue', newValue)
96+
emit('change', newValue)
9697
},
9798
})
99+
100+
const checkboxList = computed<Array<any>>(() =>
101+
(slots.first ? slotsToElements(slots.first(), slotsName, props.disabled) : [])
102+
.concat(props.options.map((e) => optionToElement(e, props)))
103+
.concat(slots.default ? slotsToElements(slots.default(), slotsName, props.disabled) : [])
104+
.map((e, idx) => bindGroupProps(e, idx, props, computedName, computedId))
105+
.map((e) => ({
106+
...e,
107+
}))
108+
)
109+
110+
const attrs = getGroupAttr(props)
111+
const classes = getGroupClasses(props)
112+
113+
// TODO: make tests compatible with the v-focus directive
98114
</script>

src/components/BFormRadio/form-radio.spec.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -969,8 +969,8 @@ describe('form-radio', () => {
969969
})
970970

971971
expect(wrapper.vm).toBeDefined()
972-
expect(wrapper.vm.modelValue).toBeDefined()
973-
expect(wrapper.vm.modelValue).toBe(null)
972+
expect(wrapper.vm.modelValue).toBeUndefined()
973+
974974
expect(wrapper.emitted('change')).toBeUndefined()
975975

976976
const $label = wrapper.find('label')
@@ -1003,8 +1003,8 @@ describe('form-radio', () => {
10031003
})
10041004

10051005
expect(wrapper.vm).toBeDefined()
1006-
expect(wrapper.vm.modelValue).toBeDefined()
1007-
expect(wrapper.vm.modelValue).toBe(null)
1006+
expect(wrapper.vm.modelValue).toBeUndefined()
1007+
10081008
expect(wrapper.emitted('change')).toBeUndefined()
10091009

10101010
const $input = wrapper.find('input')
@@ -1030,8 +1030,7 @@ describe('form-radio', () => {
10301030
})
10311031

10321032
expect(wrapper.vm).toBeDefined()
1033-
expect(wrapper.vm.modelValue).toBeDefined()
1034-
expect(wrapper.vm.modelValue).toBe(null)
1033+
expect(wrapper.vm.modelValue).toBeUndefined()
10351034
expect(wrapper.emitted('change')).toBeUndefined()
10361035

10371036
const $label = wrapper.find('label')

0 commit comments

Comments
 (0)