Skip to content

Commit

Permalink
fix(createReusableTemplate): transform attribute cases
Browse files Browse the repository at this point in the history
  • Loading branch information
94726 committed Jul 24, 2023
1 parent 4f4141a commit 453731b
Showing 1 changed file with 35 additions and 9 deletions.
44 changes: 35 additions & 9 deletions packages/core/createReusableTemplate/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,39 @@ import type { DefineComponent, Slot } from 'vue-demi'
import { defineComponent, isVue3, shallowRef, version } from 'vue-demi'
import { makeDestructurable } from '@vueuse/shared'

// copied from vue: https://github.com/vuejs/core/blob/3be4e3cbe34b394096210897c1be8deeb6d748d8/packages/shared/src/general.ts#L90-L112
function cacheStringFunction<T extends (str: string) => string>(fn: T): T {
const cache: Record<string, string> = Object.create(null)
return ((str: string) => {
const hit = cache[str]
return hit || (cache[str] = fn(str))
}) as T
}

const hyphenateRE = /\B([A-Z])/g
export const hyphenate = cacheStringFunction((str: string) =>
str.replace(hyphenateRE, '-$1').toLowerCase(),
)

const camelizeRE = /-(\w)/g
export const camelize = cacheStringFunction((str: string): string => {
return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''))
})

export type DefineTemplateComponent<
Bindings extends object,
Slots extends Record<string, Slot | undefined>,
Bindings extends object, Slots extends Record<string, Slot | undefined>,
> = DefineComponent<{}> & {
new(): { $slots: { default(_: Bindings & { $slots: Slots }): any } }
}

export type ReuseTemplateComponent<
Bindings extends object,
Slots extends Record<string, Slot | undefined>,
Bindings extends object, Slots extends Record<string, Slot | undefined>,
> = DefineComponent<Bindings> & {
new(): { $slots: Slots }
}

export type ReusableTemplatePair<
Bindings extends object,
Slots extends Record<string, Slot | undefined>,
Bindings extends object, Slots extends Record<string, Slot | undefined>,
> = [
DefineTemplateComponent<Bindings, Slots>,
ReuseTemplateComponent<Bindings, Slots>,
Expand All @@ -34,8 +50,7 @@ export type ReusableTemplatePair<
* @see https://vueuse.org/createReusableTemplate
*/
export function createReusableTemplate<
Bindings extends object,
Slots extends Record<string, Slot | undefined> = Record<string, Slot | undefined>,
Bindings extends object, Slots extends Record<string, Slot | undefined> = Record<string, Slot | undefined>,
>(): ReusableTemplatePair<Bindings, Slots> {
// compatibility: Vue 2.7 or above
if (!isVue3 && !version.startsWith('2.7.')) {
Expand All @@ -61,7 +76,7 @@ export function createReusableTemplate<
return () => {
if (!render.value && process.env.NODE_ENV !== 'production')
throw new Error('[VueUse] Failed to find the definition of reusable template')
return render.value?.({ ...attrs, $slots: slots })
return render.value?.({ ...keysToCamelKebabCase(attrs), $slots: slots })
}
},
}) as ReuseTemplateComponent<Bindings, Slots>
Expand All @@ -71,3 +86,14 @@ export function createReusableTemplate<
[define, reuse],
) as any
}

function keysToCamelKebabCase(obj: Record<string, any>) {
const newObj: typeof obj = {}
for (const key in obj) {
const camelKey = camelize(key)
const kebabKey = hyphenate(key)
newObj[camelKey] = obj[key]
newObj[kebabKey] = obj[key]
}
return newObj
}

0 comments on commit 453731b

Please sign in to comment.