Skip to content

Commit c038674

Browse files
committed
feat: create eagerComputed component
perf(useBooleanish): use eagerComputed instead since the resolved type usually can benefit from it refactor(useFormCheck): strongly type some things, and remove weakly typed others test: remove 'effect' test since it's now a shallowRef
1 parent 9a172e3 commit c038674

File tree

5 files changed

+51
-37
lines changed

5 files changed

+51
-37
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import {readonly, Ref, shallowRef, watchEffect, WatchOptionsBase} from 'vue'
2+
3+
/**
4+
* Eagerly loaded version of Vue computed. Code ported from Vueuse
5+
*
6+
* @link https://dev.to/linusborg/vue-when-a-computed-property-can-be-the-wrong-tool-195j
7+
*/
8+
export default <T>(fn: () => T, options?: WatchOptionsBase): Readonly<Ref<T>> => {
9+
const result = shallowRef()
10+
watchEffect(
11+
() => {
12+
result.value = fn()
13+
},
14+
{
15+
...options,
16+
flush: options?.flush ?? 'sync',
17+
}
18+
)
19+
20+
return readonly(result)
21+
}

packages/bootstrap-vue-3/src/composables/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import eagerComputed from './eagerComputed'
12
import useAlignment from './useAlignment'
23
import useBooleanish from './useBooleanish'
34
import {createBreadcrumb, useBreadcrumb} from './useBreadcrumb'
@@ -17,6 +18,7 @@ import {normalizeOptions} from './useFormSelect'
1718
import useId from './useId'
1819

1920
export {
21+
eagerComputed,
2022
useAlignment,
2123
createBreadcrumb,
2224
useBreadcrumb,
@@ -37,6 +39,7 @@ export {
3739
}
3840

3941
export default {
42+
eagerComputed,
4043
useAlignment,
4144
createBreadcrumb,
4245
useBooleanish,
Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
import type {Booleanish} from '../types'
2-
import {computed, ComputedRef, Ref} from 'vue'
2+
import {Ref} from 'vue'
33
import {resolveBooleanish} from '../utils'
4+
import eagerComputed from './eagerComputed'
45

56
// function useBooleanish<T>(el: Ref<Booleanish | T>): ComputedRef<boolean | T>
67
// This may possibily be used in Vue 3.3 to include Booleanish and complex types ie Booleanish | string
7-
function useBooleanish(el: Ref<Booleanish>): ComputedRef<boolean>
8-
function useBooleanish(el: Ref<Booleanish | undefined>): ComputedRef<boolean | undefined>
8+
/**
9+
* Resolves a Booleanish type reactively to type boolean
10+
*/
11+
function useBooleanish(el: Ref<Booleanish>): Readonly<Ref<boolean>>
12+
function useBooleanish(el: Ref<Booleanish | undefined>): Readonly<Ref<boolean | undefined>>
913
function useBooleanish(
1014
el: Ref<Booleanish> | Ref<Booleanish | undefined>
11-
): ComputedRef<boolean> | ComputedRef<boolean | undefined> {
12-
return computed(() => (el.value === undefined ? undefined : resolveBooleanish(el.value)))
15+
): Readonly<Ref<boolean>> | Readonly<Ref<boolean | undefined>> {
16+
return eagerComputed(() => (el.value === undefined ? undefined : resolveBooleanish(el.value)))
1317
}
1418

1519
export default useBooleanish

packages/bootstrap-vue-3/src/composables/useFormCheck.ts

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,24 @@ const getClasses = (items: {
1212
inline?: boolean
1313
switch?: boolean
1414
size?: InputSize
15-
}): ComputedRef =>
15+
}) =>
1616
computed(() => ({
1717
'form-check': !items.plain && !items.button,
18-
'form-check-inline': items.inline,
19-
'form-switch': items.switch,
20-
[`form-control-${items.size}`]: items.size && items.size !== 'md',
18+
'form-check-inline': items.inline === true,
19+
'form-switch': items.switch === true,
20+
[`form-control-${items.size}`]: items.size !== undefined && items.size !== 'md',
2121
}))
2222

2323
/**
2424
* @param items must be a reactive object ex: reactive({ plain: toRef(plainBoolean, 'value')})
2525
* @returns
2626
*/
27-
const getInputClasses = (items: {
28-
plain?: boolean
29-
button?: boolean
30-
state?: boolean
31-
}): ComputedRef =>
27+
const getInputClasses = (items: {plain?: boolean; button?: boolean; state?: boolean}) =>
3228
computed(() => ({
3329
'form-check-input': !items.plain && !items.button,
3430
'is-valid': items.state === true,
3531
'is-invalid': items.state === false,
36-
'btn-check': items.button,
32+
'btn-check': items.button === true,
3733
}))
3834

3935
/**
@@ -45,26 +41,22 @@ const getLabelClasses = (items: {
4541
button?: boolean
4642
buttonVariant?: ButtonVariant
4743
size?: InputSize
48-
}): ComputedRef =>
44+
}) =>
4945
computed(() => ({
5046
'form-check-label': !items.plain && !items.button,
51-
'btn': items.button,
52-
[`btn-${items.buttonVariant}`]: items.button,
47+
'btn': items.button === true,
48+
[`btn-${items.buttonVariant}`]: items.button === true && items.buttonVariant !== undefined,
5349
[`btn-${items.size}`]: items.button && items.size && items.size !== 'md',
5450
}))
5551

5652
/**
5753
* @param items must be a reactive object ex: reactive({ plain: toRef(plainBoolean, 'value')})
5854
* @returns
5955
*/
60-
const getGroupAttr = (items: {
61-
required?: boolean
62-
ariaInvalid?: AriaInvalid
63-
state?: boolean
64-
}): ComputedRef =>
56+
const getGroupAttr = (items: {required?: boolean; ariaInvalid?: AriaInvalid; state?: boolean}) =>
6557
computed(() => ({
6658
'aria-invalid': resolveAriaInvalid(items.ariaInvalid, items.state),
67-
'aria-required': items.required?.toString() === 'true' ? 'true' : null,
59+
'aria-required': items.required === true ? true : undefined,
6860
}))
6961

7062
/**
@@ -76,12 +68,12 @@ const getGroupClasses = (items: {
7668
buttons?: boolean
7769
stacked?: boolean
7870
size?: InputSize
79-
}): ComputedRef =>
71+
}) =>
8072
computed(() => ({
81-
'was-validated': items.validated,
82-
'btn-group': items.buttons && !items.stacked,
83-
'btn-group-vertical': items.stacked,
84-
[`btn-group-${items.size}`]: items.size,
73+
'was-validated': items.validated === true,
74+
'btn-group': items.buttons === true && !items.stacked,
75+
'btn-group-vertical': items.stacked === true,
76+
[`btn-group-${items.size}`]: items.size !== undefined,
8577
}))
8678

8779
// TODO this function is similarly used in BTabs and may be capable of being a util function
@@ -155,8 +147,8 @@ const bindGroupProps = (
155147
el: any,
156148
idx: number,
157149
props: any,
158-
computedName: ComputedRef,
159-
computedId: ComputedRef
150+
computedName: ComputedRef<string>,
151+
computedId: ComputedRef<string>
160152
): any => ({
161153
...el,
162154
props: {

packages/bootstrap-vue-3/tests/composables/useBooleanish.spec.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,6 @@ describe('useBooleanish blackbox test', () => {
1111
expect(value).toHaveProperty('value')
1212
})
1313

14-
it('value to contain property effect', () => {
15-
const prop: {value: Booleanish} = {value: 'false'}
16-
const value = useBooleanish(toRef(prop, 'value'))
17-
expect(value).toHaveProperty('effect')
18-
})
19-
2014
it("value to return bool false, when 'false'", () => {
2115
const prop: {value: Booleanish} = {value: 'false'}
2216
const value = useBooleanish(toRef(prop, 'value'))

0 commit comments

Comments
 (0)