Skip to content

Commit 2bfc591

Browse files
author
issayah
committed
BFormSelect script setup conversion and fixes
1 parent 9726d10 commit 2bfc591

File tree

3 files changed

+152
-137
lines changed

3 files changed

+152
-137
lines changed

src/components/BFormSelect/BFormSelect.vue

Lines changed: 121 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
v-model="localValue"
77
:class="classes"
88
:name="name"
9-
:form="form || null"
10-
:multiple="multiple || null"
9+
:form="form || undefined"
10+
:multiple="multiple || undefined"
1111
:size="computedSelectSize"
1212
:disabled="disabled"
1313
:required="required"
14-
:aria-required="required ? 'true' : null"
14+
:aria-required="required ? true : undefined"
1515
:aria-invalid="computedAriaInvalid"
1616
>
1717
<slot name="first" />
@@ -36,122 +36,137 @@
3636
</select>
3737
</template>
3838

39-
<script lang="ts">
40-
import {computed, defineComponent, nextTick, onActivated, onMounted, PropType, ref} from 'vue'
39+
<script setup lang="ts">
40+
// import type {BFormSelectEmits, BFormSelectProps} from '@/types/components'
41+
import type {Size} from '@/types'
42+
import {computed, nextTick, onActivated, onMounted, ref} from 'vue'
4143
import BFormSelectOption from './BFormSelectOption.vue'
4244
import BFormSelectOptionGroup from './BFormSelectOptionGroup.vue'
43-
import useId from '../../composables/useId'
44-
import {Size} from '../../types'
45-
import {normalizeOptions} from '../../composables/useFormSelect'
45+
import useId from '@/composables/useId'
46+
import {normalizeOptions} from '@/composables/useFormSelect'
4647
47-
export default defineComponent({
48-
name: 'BFormSelect',
49-
components: {BFormSelectOption, BFormSelectOptionGroup},
50-
props: {
51-
ariaInvalid: {
52-
type: [Boolean, String] as PropType<boolean | 'false' | 'true' | 'grammar' | 'spelling'>,
53-
default: false,
54-
},
55-
autofocus: {type: Boolean, default: false},
56-
disabled: {type: Boolean, default: false},
57-
disabledField: {type: String, default: 'disabled'},
58-
form: {type: String, required: false},
59-
htmlField: {type: String, default: 'html'},
60-
id: {type: String, required: false},
61-
labelField: {type: String, default: 'label'},
62-
multiple: {type: Boolean, default: false},
63-
name: {type: String, required: false},
64-
options: {type: [Array, Object], default: () => []},
65-
optionsField: {type: String, default: 'options'},
66-
plain: {type: Boolean, default: false},
67-
required: {type: Boolean, default: false},
68-
selectSize: {type: Number, default: 0},
69-
size: {type: String as PropType<Size>, required: false},
70-
state: {
71-
type: Boolean as PropType<boolean | null | undefined>,
72-
default: null,
73-
},
74-
textField: {type: String, default: 'text'},
75-
valueField: {type: String, default: 'value'},
76-
modelValue: {type: [String, Array, Object, Number], default: ''},
77-
},
78-
emits: ['update:modelValue', 'change', 'input'],
79-
setup(props, {emit}) {
80-
const input = ref<HTMLElement>()
81-
const computedId = useId(props.id, 'input')
82-
83-
// lifecycle events
84-
const handleAutofocus = () => {
85-
nextTick(() => {
86-
if (props.autofocus) input.value?.focus()
87-
})
88-
}
89-
onMounted(handleAutofocus)
90-
onActivated(handleAutofocus)
91-
// /lifecycle events
48+
interface BFormSelectProps {
49+
ariaInvalid?: boolean | 'grammar' | 'spelling'
50+
autofocus?: boolean
51+
disabled?: boolean
52+
disabledField?: string
53+
form?: string
54+
htmlField?: string
55+
id?: string
56+
labelField?: string
57+
multiple?: boolean
58+
name?: string
59+
options?: Array<unknown> | Record<string, unknown>
60+
optionsField?: string
61+
plain?: boolean
62+
required?: boolean
63+
selectSize?: number
64+
size?: Size
65+
state?: boolean
66+
textField?: string
67+
valueField?: string
68+
modelValue?: string | Array<unknown> | Record<string, unknown> | number
69+
}
9270
93-
// computed
94-
const classes = computed(() => ({
95-
'form-control': props.plain,
96-
[`form-control-${props.size}`]: props.size && props.plain,
97-
'form-select': !props.plain,
98-
[`form-select-${props.size}`]: props.size && !props.plain,
99-
'is-valid': props.state === true,
100-
'is-invalid': props.state === false,
101-
}))
71+
const props = withDefaults(defineProps<BFormSelectProps>(), {
72+
ariaInvalid: false,
73+
autofocus: false,
74+
disabled: false,
75+
disabledField: 'disabled',
76+
htmlField: 'html',
77+
labelField: 'label',
78+
multiple: false,
79+
options: () => [],
80+
optionsField: 'options',
81+
plain: false,
82+
required: false,
83+
selectSize: 0,
84+
state: undefined,
85+
textField: 'text',
86+
valueField: 'value',
87+
modelValue: '',
88+
})
10289
103-
const computedSelectSize = computed(() => {
104-
if (props.selectSize || props.plain) {
105-
return props.selectSize
106-
}
107-
return null
108-
})
90+
interface BFormSelectEmits {
91+
(e: 'input', value: unknown): void
92+
(e: 'update:modelValue', value: unknown): void
93+
(e: 'change', value: unknown): void
94+
}
10995
110-
const computedAriaInvalid = computed(() => {
111-
if (props.ariaInvalid) {
112-
return props.ariaInvalid.toString()
113-
}
114-
return props.state === false ? 'true' : null
115-
})
96+
const emit = defineEmits<BFormSelectEmits>()
11697
117-
const formOptions = computed(() => normalizeOptions(props.options, 'BFormSelect', props))
118-
const localValue = computed({
119-
get() {
120-
return props.modelValue
121-
},
122-
set(newValue: any) {
123-
emit('change', newValue)
124-
emit('update:modelValue', newValue)
125-
emit('input', newValue)
126-
},
127-
})
98+
const input = ref<HTMLElement>()
99+
const computedId = useId(props.id, 'input')
128100
129-
// /computed
101+
// lifecycle events
102+
const handleAutofocus = () => {
103+
nextTick(() => {
104+
if (props.autofocus) input.value?.focus()
105+
})
106+
}
107+
onMounted(handleAutofocus)
108+
onActivated(handleAutofocus)
109+
// /lifecycle events
130110
131-
// methods
111+
// computed
112+
const classes = computed(() => ({
113+
'form-control': props.plain,
114+
[`form-control-${props.size}`]: props.size && props.plain,
115+
'form-select': !props.plain,
116+
[`form-select-${props.size}`]: props.size && !props.plain,
117+
'is-valid': props.state === true,
118+
'is-invalid': props.state === false,
119+
}))
132120
133-
const focus = () => {
134-
if (!props.disabled) input.value?.focus()
135-
}
121+
const computedSelectSize = computed<number | undefined>(() => {
122+
if (props.selectSize || props.plain) {
123+
return props.selectSize
124+
}
125+
return undefined
126+
})
136127
137-
const blur = () => {
138-
if (!props.disabled) {
139-
input.value?.blur()
140-
}
128+
const computedAriaInvalid = computed<'grammar' | 'spelling' | boolean | undefined>(() => {
129+
if (props.state === false) {
130+
return true
131+
}
132+
if (props.state === true) {
133+
return undefined
134+
}
135+
if (typeof props.ariaInvalid === 'boolean') {
136+
if (props.ariaInvalid === false) {
137+
return undefined
141138
}
142-
// /methods
139+
return props.ariaInvalid
140+
}
141+
return props.ariaInvalid
142+
})
143143
144-
return {
145-
input,
146-
computedId,
147-
computedSelectSize,
148-
computedAriaInvalid,
149-
classes,
150-
formOptions,
151-
localValue,
152-
focus,
153-
blur,
154-
}
144+
const formOptions = computed(() =>
145+
normalizeOptions(props.options as Array<any>, 'BFormSelect', props)
146+
)
147+
const localValue = computed({
148+
get() {
149+
return props.modelValue
150+
},
151+
set(newValue: any) {
152+
emit('change', newValue)
153+
emit('update:modelValue', newValue)
154+
emit('input', newValue)
155155
},
156156
})
157+
158+
// /computed
159+
160+
// methods
161+
162+
const focus = () => {
163+
if (!props.disabled) input.value?.focus()
164+
}
165+
166+
const blur = () => {
167+
if (!props.disabled) {
168+
input.value?.blur()
169+
}
170+
}
171+
// /methods
157172
</script>

src/components/BFormSelect/BFormSelectOption.vue

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
</option>
55
</template>
66

7-
<script lang="ts">
8-
import {defineComponent} from 'vue'
7+
<script setup lang="ts">
8+
// import type {BFormSelectOptionProps} from '@/types/components'
99
10-
export default defineComponent({
11-
name: 'BFormSelectOption',
12-
props: {
13-
// eslint-disable-next-line vue/require-prop-types
14-
value: {required: true},
15-
disabled: {type: Boolean, default: false},
16-
},
10+
interface BFormSelectOptionProps {
11+
value: unknown
12+
disabled?: boolean
13+
}
14+
15+
withDefaults(defineProps<BFormSelectOptionProps>(), {
16+
disabled: false,
1717
})
1818
</script>

src/components/BFormSelect/BFormSelectOptionGroup.vue

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,30 @@
1515
</optgroup>
1616
</template>
1717

18-
<script lang="ts">
19-
import {computed, defineComponent} from 'vue'
18+
<script setup lang="ts">
19+
// import type {BFormSelectOptionGroupProps} from '@/types/components'
20+
import {computed} from 'vue'
2021
import BFormSelectOption from './BFormSelectOption.vue'
21-
import {normalizeOptions} from '../../composables/useFormSelect'
22+
import {normalizeOptions} from '@/composables/useFormSelect'
2223
23-
export default defineComponent({
24-
name: 'BFormSelectOptionGroup',
25-
components: {BFormSelectOption},
26-
props: {
27-
label: {type: String, required: true},
28-
disabledField: {type: String, default: 'disabled'},
29-
htmlField: {type: String, default: 'html'},
30-
options: {type: [Array, Object], default: () => []},
31-
textField: {type: String, default: 'text'},
32-
valueField: {type: String, default: 'value'},
33-
},
34-
setup(props) {
35-
const formOptions = computed(() =>
36-
normalizeOptions(props.options as any, 'BFormSelectOptionGroup', props)
37-
)
24+
interface BFormSelectOptionGroupProps {
25+
label?: string
26+
disabledField?: string
27+
htmlField?: string
28+
options?: Array<unknown> | Record<string, unknown>
29+
textField?: string
30+
valueField?: string
31+
}
3832
39-
return {
40-
formOptions,
41-
}
42-
},
33+
const props = withDefaults(defineProps<BFormSelectOptionGroupProps>(), {
34+
disabledField: 'disabled',
35+
htmlField: 'html',
36+
options: () => [],
37+
textField: 'text',
38+
valueField: 'value',
4339
})
40+
41+
const formOptions = computed(() =>
42+
normalizeOptions(props.options as Array<any>, 'BFormSelectOptionGroup', props)
43+
)
4444
</script>

0 commit comments

Comments
 (0)