Skip to content

Commit

Permalink
TypeScript Rollout Tier 8 - Select (#368)
Browse files Browse the repository at this point in the history
* feat(lib): rewrite Select in TS

Rewrites `components/select/Select.vue` in TypeScript:
- Replaces chaining of `emit` and `checkHtml5Validity` on blur events
  with a call of the `onBlur` method provided by `FormElementMixin`.
  This also fixes the issue @ntohq/buefy-next#271.
- Casts `modelValue` as `ModelValue` which is equal to `any` (see
  below), because Vue fails to infer the prop type if the `type` array
  includes `null` and ends up with failing to infer the entire component
  type. Explicitly casting `modelValue` with `PropType` works around the
  problem.
- Introduces a new type `ModelValue` which represents the type of the
  `modelValue` prop to avoid spreading `any` all around the code. I
  chose `any` for the model value type, because it is intended to accept
  any values.
- Trivial changes:
  - Imports `BIcon` and explicitly gives it the name when it is
    registered so that type checking works. No type checking works on
    globally registered components
  - Gives minimal types
  - Adds `lang="ts"` to the `setup` section
  - Wraps the entire component with a `defineComponent` call
  - Makes a comment non-JSDoc style so that `@microsoft/api-extractor`
    won't pick it up

Rewrites `components/select/index` in TypeScript:
- Replaces the extension: `.js` → `.ts`
- Types the `Plugin.install` method

* test(lib): rewrite Select.spec in TS

Rewrites `components/select/Select.spec` in TypeScript. Changes are all
straightforward:
- Replaces the extension: `.js` → `.ts`
- Imports necessary functions from `vitest`
- Appends the `.vue` extension to the line importing `BSelect`
- Types `wrapper` with `VueWrapper`

Replaces the test snapshot in `components/select/__snapshots__`:
- `Select.spec.js.snap` → `Select.spec.ts.snap`

* chore(lib): bundle select as TS

`rollup.config.mjs` removes "select" from `JS_COMPONENTS`.

* feat(docs): rewrite Select docs in TS

Rewrites docs for `Select` in `pages/components/select`. All the changes
are straightforward.

Here is a TypeScript migration tip:
- Explicitly import and register components so that they are type
  checked. No type-checking is performed for globally registered
  components.
  • Loading branch information
kikuomax authored Jan 11, 2025
1 parent 6abb6e0 commit 6e553fe
Show file tree
Hide file tree
Showing 12 changed files with 78 additions and 33 deletions.
1 change: 0 additions & 1 deletion packages/buefy-next/rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ const JS_COMPONENTS = [
'dialog',
'notification',
'numberinput',
'select',
'table',
'timepicker',
'upload',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { shallowMount } from '@vue/test-utils'
import BSelect from '@components/select/Select'
import type { VueWrapper } from '@vue/test-utils'
import { beforeEach, describe, expect, it } from 'vitest'
import BSelect from '@components/select/Select.vue'

let wrapper
let wrapper: VueWrapper<InstanceType<typeof BSelect>>

describe('BSelect', () => {
beforeEach(() => {
Expand Down
33 changes: 23 additions & 10 deletions packages/buefy-next/src/components/select/Select.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
:multiple="multiple"
:size="nativeSize"
v-bind="fallthroughAttrs"
@blur="$emit('blur', $event) && checkHtml5Validity()"
@blur="onBlur"
@focus="$emit('focus', $event)"
>

Expand Down Expand Up @@ -42,27 +42,40 @@
</div>
</template>

<script>
import Icon from '../icon/Icon.vue'
<script lang="ts">
import { defineComponent } from 'vue'
import type { PropType } from 'vue'
import BIcon from '../icon/Icon.vue'
import CompatFallthroughMixin from '../../utils/CompatFallthroughMixin'
import FormElementMixin from '../../utils/FormElementMixin'
export default {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type ModelValue = any
export default defineComponent({
name: 'BSelect',
components: {
[Icon.name]: Icon
BIcon
},
mixins: [CompatFallthroughMixin, FormElementMixin],
props: {
modelValue: {
type: [String, Number, Boolean, Object, Array, Function, Date, null],
type: [
String, Number, Boolean, Object, Array, Function, Date, null
] as PropType<ModelValue>,
default: null
},
placeholder: String,
multiple: Boolean,
nativeSize: [String, Number]
},
emits: ['blur', 'focus', 'update:modelValue'],
emits: {
/* eslint-disable @typescript-eslint/no-unused-vars */
blur: (_event: FocusEvent) => true,
focus: (_event: FocusEvent) => true,
'update:modelValue': (_value: ModelValue) => true
/* eslint-enable @typescript-eslint/no-unused-vars */
},
data() {
return {
selected: this.modelValue,
Expand All @@ -74,7 +87,7 @@ export default {
get() {
return this.selected
},
set(value) {
set(value: ModelValue) {
this.selected = value
this.$emit('update:modelValue', value)
!this.isValid && this.checkHtml5Validity()
Expand All @@ -91,7 +104,7 @@ export default {
}
},
watch: {
/**
/*
* When v-model is changed:
* 1. Set the selected option.
* 2. If it's invalid, validate again.
Expand All @@ -101,5 +114,5 @@ export default {
!this.isValid && this.checkHtml5Validity()
}
}
}
})
</script>

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`BSelect > render correctly 1`] = `
"<div class=\\"control\\"><span class=\\"select is-empty\\"><select><!--v-if--></select></span>
<!--v-if-->
</div>"
`;
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import type { App } from 'vue'
import Select from './Select.vue'

import { registerComponent } from '../../utils/plugins'

const Plugin = {
install(Vue) {
install(Vue: App) {
registerComponent(Vue, Select)
}
}
Expand Down
25 changes: 17 additions & 8 deletions packages/docs/src/pages/components/select/Select.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,32 @@
</div>
</template>

<script>
import api from './api/select'
<script lang="ts">
import { defineComponent } from 'vue'
import { shallowFields } from '@/utils'
import ApiView from '@/components/ApiView.vue'
import Example from '@/components/Example.vue'
import api from './api/select'
import ExSimple from './examples/ExSimple'
import ExSimple from './examples/ExSimple.vue'
import ExSimpleCode from './examples/ExSimple.vue?raw'
import ExMultiple from './examples/ExMultiple'
import ExMultiple from './examples/ExMultiple.vue'
import ExMultipleCode from './examples/ExMultiple.vue?raw'
import ExIcons from './examples/ExIcons'
import ExIcons from './examples/ExIcons.vue'
import ExIconsCode from './examples/ExIcons.vue?raw'
import ExSizes from './examples/ExSizes'
import ExSizes from './examples/ExSizes.vue'
import ExSizesCode from './examples/ExSizes.vue?raw'
export default {
export default defineComponent({
components: {
ApiView,
Example
},
data() {
return {
api,
Expand All @@ -44,5 +53,5 @@
ExSizesCode
}
}
}
})
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,7 @@
</b-field>
</section>
</template>

<script setup lang="ts">
import { BField, BSelect } from '@ntohq/buefy-next'
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,15 @@
</section>
</template>

<script>
<script lang="ts">
import { defineComponent } from 'vue'
import { BField, BSelect } from '@ntohq/buefy-next'
export default {
components: {
BField,
BSelect
},
data() {
return {
selectedOptions: []
Expand Down
12 changes: 9 additions & 3 deletions packages/docs/src/pages/components/select/examples/ExSimple.vue
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,18 @@
</section>
</template>

<script>
<script lang="ts">
import { defineComponent } from 'vue'
import data from '@/data/sample.json'
import { BField, BSelect } from '@ntohq/buefy-next'
export default {
export default defineComponent({
components: {
BField,
BSelect
},
data() {
return { data }
}
}
})
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,7 @@
</b-field>
</section>
</template>

<script setup lang="ts">
import { BField, BSelect } from '@ntohq/buefy-next'
</script>

0 comments on commit 6e553fe

Please sign in to comment.