Skip to content
This repository was archived by the owner on Mar 27, 2025. It is now read-only.

Commit 6902826

Browse files
committed
refactor: pluckProps => pick
refactor: improve ts for pick refactor: improve ts for omit chore: move pick to object.ts fix(omit): can properly omit number values
1 parent 4179796 commit 6902826

File tree

12 files changed

+165
-227
lines changed

12 files changed

+165
-227
lines changed

packages/bootstrap-vue-next/src/components/BAvatar/BAvatar.vue

+20-27
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,7 @@
2424
</template>
2525

2626
<script setup lang="ts">
27-
import {
28-
avatarGroupInjectionKey,
29-
isEmptySlot,
30-
isLink,
31-
isNumeric,
32-
pluckProps,
33-
toFloat,
34-
} from '../../utils'
27+
import {avatarGroupInjectionKey, isEmptySlot, isLink, isNumeric, pick, toFloat} from '../../utils'
3528
import {computed, type CSSProperties, inject, type StyleValue, useSlots} from 'vue'
3629
import type {Booleanish, ButtonType, ColorVariant, Size, TextColorVariant} from '../../types'
3730
import {useBooleanish} from '../../composables'
@@ -151,25 +144,25 @@ const computedAttrs = computed(() => ({
151144
'disabled': disabledBoolean.value || null,
152145
// Link props
153146
...(computedLink.value
154-
? pluckProps(props, {
155-
active: true,
156-
activeClass: true,
157-
append: true,
158-
href: true,
159-
rel: true,
160-
replace: true,
161-
routerComponentName: true,
162-
target: true,
163-
to: true,
164-
variant: true,
165-
opacity: true,
166-
opacityHover: true,
167-
underlineVariant: true,
168-
underlineOffset: true,
169-
underlineOffsetHover: true,
170-
underlineOpacity: true,
171-
underlineOpacityHover: true,
172-
} as Record<keyof Omit<BLinkProps, 'event' | 'routerTag'>, true>)
147+
? pick(props, [
148+
'active',
149+
'activeClass',
150+
'append',
151+
'href',
152+
'rel',
153+
'replace',
154+
'routerComponentName',
155+
'target',
156+
'to',
157+
'variant',
158+
'opacity',
159+
'opacityHover',
160+
'underlineVariant',
161+
'underlineOffset',
162+
'underlineOffsetHover',
163+
'underlineOpacity',
164+
'underlineOpacityHover',
165+
])
173166
: {}),
174167
}))
175168

packages/bootstrap-vue-next/src/components/BBadge/BBadge.vue

+22-22
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
</template>
66

77
<script setup lang="ts">
8-
import {isLink, pluckProps} from '../../utils'
8+
import {isLink, pick} from '../../utils'
99
import {useBooleanish} from '../../composables'
1010
import {computed} from 'vue'
1111
import type {Booleanish} from '../../types'
@@ -81,27 +81,27 @@ const computedClasses = computed(() => ({
8181
8282
const computedLinkProps = computed(() =>
8383
computedLink.value
84-
? pluckProps(props, {
85-
active: true,
86-
activeClass: true,
87-
append: true,
88-
disabled: true,
89-
href: true,
90-
rel: true,
91-
replace: true,
92-
routerComponentName: true,
93-
target: true,
94-
to: true,
95-
variant: true,
96-
opacity: true,
97-
opacityHover: true,
98-
underlineVariant: true,
99-
underlineOffset: true,
100-
underlineOffsetHover: true,
101-
underlineOpacity: true,
102-
underlineOpacityHover: true,
103-
icon: true,
104-
} satisfies Record<keyof Omit<BLinkProps, 'event' | 'routerTag'>, true>)
84+
? pick(props, [
85+
'active',
86+
'activeClass',
87+
'append',
88+
'disabled',
89+
'href',
90+
'rel',
91+
'replace',
92+
'routerComponentName',
93+
'target',
94+
'to',
95+
'variant',
96+
'opacity',
97+
'opacityHover',
98+
'underlineVariant',
99+
'underlineOffset',
100+
'underlineOffsetHover',
101+
'underlineOpacity',
102+
'underlineOpacityHover',
103+
'icon',
104+
])
105105
: {}
106106
)
107107
</script>

packages/bootstrap-vue-next/src/components/BBreadcrumb/BBreadcrumbItem.vue

+22-22
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
</template>
1515

1616
<script setup lang="ts">
17-
import {pluckProps} from '../../utils'
17+
import {pick} from '../../utils'
1818
import {useBooleanish} from '../../composables'
1919
import {computed} from 'vue'
2020
import BLink from '../BLink/BLink.vue'
@@ -80,27 +80,27 @@ const computedAriaCurrent = computed(() => (activeBoolean.value ? props.ariaCurr
8080
8181
const computedLinkProps = computed(() =>
8282
computedTag.value !== 'span'
83-
? pluckProps(props, {
84-
active: true,
85-
activeClass: true,
86-
append: true,
87-
disabled: true,
88-
href: true,
89-
rel: true,
90-
replace: true,
91-
routerComponentName: true,
92-
target: true,
93-
to: true,
94-
variant: true,
95-
opacity: true,
96-
opacityHover: true,
97-
underlineVariant: true,
98-
underlineOffset: true,
99-
underlineOffsetHover: true,
100-
underlineOpacity: true,
101-
underlineOpacityHover: true,
102-
icon: true,
103-
} satisfies Record<keyof Omit<BLinkProps, 'event' | 'routerTag'>, true>)
83+
? pick(props, [
84+
'active',
85+
'activeClass',
86+
'append',
87+
'disabled',
88+
'href',
89+
'rel',
90+
'replace',
91+
'routerComponentName',
92+
'target',
93+
'to',
94+
'variant',
95+
'opacity',
96+
'opacityHover',
97+
'underlineVariant',
98+
'underlineOffset',
99+
'underlineOffsetHover',
100+
'underlineOpacity',
101+
'underlineOpacityHover',
102+
'icon',
103+
])
104104
: {}
105105
)
106106

packages/bootstrap-vue-next/src/components/BNav/BNavItem.vue

+22-22
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {computed} from 'vue'
1919
import BLink from '../BLink/BLink.vue'
2020
import {useBooleanish} from '../../composables'
2121
import type {BLinkProps} from '../../types/BLinkProps'
22-
import {pluckProps} from '../../utils'
22+
import {pick} from '../../utils'
2323
2424
defineSlots<{
2525
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -69,26 +69,26 @@ const emit = defineEmits<{
6969
const disabledBoolean = useBooleanish(() => props.disabled)
7070
7171
const linkProps = computed(() =>
72-
pluckProps(props, {
73-
active: true,
74-
activeClass: true,
75-
append: true,
76-
disabled: true,
77-
href: true,
78-
icon: true,
79-
opacity: true,
80-
opacityHover: true,
81-
rel: true,
82-
replace: true,
83-
routerComponentName: true,
84-
target: true,
85-
to: true,
86-
underlineOffset: true,
87-
underlineOffsetHover: true,
88-
underlineOpacity: true,
89-
underlineOpacityHover: true,
90-
underlineVariant: true,
91-
variant: true,
92-
} satisfies Record<keyof Omit<BLinkProps, 'event' | 'routerTag'>, true>)
72+
pick(props, [
73+
'active',
74+
'activeClass',
75+
'append',
76+
'disabled',
77+
'href',
78+
'icon',
79+
'opacity',
80+
'opacityHover',
81+
'rel',
82+
'replace',
83+
'routerComponentName',
84+
'target',
85+
'to',
86+
'underlineOffset',
87+
'underlineOffsetHover',
88+
'underlineOpacity',
89+
'underlineOpacityHover',
90+
'underlineVariant',
91+
'variant',
92+
])
9393
)
9494
</script>

packages/bootstrap-vue-next/src/components/BNav/BNavItemDropdown.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ const dropdownValue = computed({
9898
modelValue.value = value
9999
},
100100
})
101-
const usableProps = computed(() => omit(props, ['modelValue'] as const))
101+
const usableProps = computed(() => omit(props, ['modelValue']))
102102
103103
const close = () => {
104104
modelValue.value = false

packages/bootstrap-vue-next/src/components/BNavbar/BNavbarBrand.vue

+22-22
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
</template>
66

77
<script setup lang="ts">
8-
import {isLink, pluckProps} from '../../utils'
8+
import {isLink, pick} from '../../utils'
99
import {computed} from 'vue'
1010
import BLink from '../BLink/BLink.vue'
1111
import type {BLinkProps} from '../../types/BLinkProps'
@@ -54,27 +54,27 @@ const computedTag = computed<string | typeof BLink>(() => (computedLink.value ?
5454
5555
const computedLinkProps = computed(() =>
5656
computedLink.value
57-
? pluckProps(props, {
58-
active: true,
59-
activeClass: true,
60-
append: true,
61-
disabled: true,
62-
href: true,
63-
rel: true,
64-
replace: true,
65-
routerComponentName: true,
66-
target: true,
67-
to: true,
68-
variant: true,
69-
opacity: true,
70-
opacityHover: true,
71-
underlineVariant: true,
72-
underlineOffset: true,
73-
underlineOffsetHover: true,
74-
underlineOpacity: true,
75-
underlineOpacityHover: true,
76-
icon: true,
77-
} satisfies Record<keyof Omit<BLinkProps, 'event' | 'routerTag'>, true>)
57+
? pick(props, [
58+
'active',
59+
'activeClass',
60+
'append',
61+
'disabled',
62+
'href',
63+
'rel',
64+
'replace',
65+
'routerComponentName',
66+
'target',
67+
'to',
68+
'variant',
69+
'opacity',
70+
'opacityHover',
71+
'underlineVariant',
72+
'underlineOffset',
73+
'underlineOffsetHover',
74+
'underlineOpacity',
75+
'underlineOpacityHover',
76+
'icon',
77+
])
7878
: {}
7979
)
8080
</script>
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,32 @@
11
/**
22
* Removes properties from an object, based on the values in an array, and returns the new object.
33
* Equivalent to an object version of TS Omit<>
4-
*
5-
* @param {Record<PropertyKey, unknown>} objToPluck
6-
* @param {ReadonlyArray<PropertyKey>} keysToPluck
7-
* @returns
84
*/
9-
export const omit = <A extends Record<PropertyKey, unknown>, B extends ReadonlyArray<PropertyKey>>(
5+
export const omit = <
6+
A extends Record<PropertyKey, unknown>,
7+
const B extends ReadonlyArray<PropertyKey>
8+
>(
109
objToPluck: A,
11-
keysToPluck: B
10+
keysToPluck: B | (keyof A)[]
1211
): Omit<A, B[number]> =>
1312
Object.keys(objToPluck)
14-
.filter((key) => !keysToPluck.includes(key))
13+
.filter(
14+
(key) => !keysToPluck.map((el) => (typeof el === 'string' ? el : el.toString())).includes(key)
15+
)
1516
.reduce((result, key) => ({...result, [key]: objToPluck[key]}), {} as Omit<A, B[number]>)
17+
18+
/**
19+
* Picks properties from an object, base on the values in an array, and returns the new object.
20+
* Equivalent to an object version of TS Pick<>
21+
*/
22+
export const pick = <
23+
A extends Record<PropertyKey, unknown>,
24+
const B extends ReadonlyArray<PropertyKey>
25+
>(
26+
objToPluck: A,
27+
keysToPluck: B | (keyof A)[]
28+
): Pick<A, B[number]> =>
29+
[...keysToPluck].reduce((memo, prop) => {
30+
memo[prop] = objToPluck[prop]
31+
return memo
32+
}, {} as Record<PropertyKey, unknown>) as Pick<A, B[number]>

packages/bootstrap-vue-next/src/utils/props.ts

-23
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,3 @@ import {upperFirst} from './stringUtils'
1212
*/
1313
export const suffixPropName = (suffix: string, value: string): string =>
1414
value + (suffix ? upperFirst(suffix) : '')
15-
16-
/**
17-
* Given an array of properties or an object of property keys, plucks all the values off the target object, returning a new object that has props that reference the original prop values.
18-
* An object equivelent to TS Pick<>
19-
*
20-
* @param {ReadonlyArray<PropertyKey> | Record<PropertyKey, unknown>} keysToPluck
21-
* @param {Record<PropertyKey, unknown>} objToPluck
22-
* @returns
23-
*/
24-
export const pluckProps = <
25-
A extends Record<PropertyKey, unknown>,
26-
B extends ReadonlyArray<PropertyKey> | Record<PropertyKey, unknown>
27-
>(
28-
objToPluck: A,
29-
keysToPluck: B
30-
): B extends readonly PropertyKey[] ? Pick<A, B[number]> : Pick<A, keyof B> =>
31-
(Array.isArray(keysToPluck) ? keysToPluck.slice() : Object.keys(keysToPluck)).reduce(
32-
(memo, prop) => {
33-
memo[prop] = objToPluck[prop]
34-
return memo
35-
},
36-
{}
37-
)

0 commit comments

Comments
 (0)