You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
3.9 KiB
127 lines
3.9 KiB
import { computed, getCurrentInstance, inject, isRef, ref, unref } from 'vue'
|
|
|
|
import type { InjectionKey, MaybeRef, Ref } from 'vue'
|
|
|
|
export const defaultNamespace = 'bo'
|
|
const statePrefix = 'is-'
|
|
|
|
const _bem = (
|
|
namespace: string,
|
|
block: string,
|
|
blockSuffix: string,
|
|
element: string,
|
|
modifier: string
|
|
) => {
|
|
let cls = `${namespace}-${block}`
|
|
if (blockSuffix) {
|
|
cls += `-${blockSuffix}`
|
|
}
|
|
if (element) {
|
|
cls += `__${element}`
|
|
}
|
|
if (modifier) {
|
|
cls += `--${modifier}`
|
|
}
|
|
return cls
|
|
}
|
|
|
|
export const namespaceContextKey: InjectionKey<Ref<string | undefined>> =
|
|
Symbol('namespaceContextKey')
|
|
|
|
/**
|
|
* 获取上下文的命名空间
|
|
* @param namespaceOverrides 覆盖命令空间
|
|
* @returns 覆盖后的命令空间
|
|
*/
|
|
export const useGetDerivedNamespace = (namespaceOverrides?: Ref<string | undefined>) => {
|
|
const derivedNamespace =
|
|
namespaceOverrides ||
|
|
(getCurrentInstance()
|
|
? inject(namespaceContextKey, ref(defaultNamespace))
|
|
: ref(defaultNamespace))
|
|
const namespace = computed(() => {
|
|
return unref(derivedNamespace) || defaultNamespace
|
|
})
|
|
return namespace
|
|
}
|
|
|
|
export const useNamespace = (
|
|
block: MaybeRef<string>,
|
|
namespaceOverrides?: Ref<string | undefined>
|
|
) => {
|
|
const namespace = useGetDerivedNamespace(namespaceOverrides)
|
|
const getBlock = () => (isRef(block) ? block.value : block)
|
|
const b = (blockSuffix = '') => _bem(namespace.value, getBlock(), blockSuffix, '', '') // bo-button-test
|
|
const e = (element?: string) =>
|
|
element ? _bem(namespace.value, getBlock(), '', element, '') : '' // bo-button__test
|
|
const m = (modifier?: string) =>
|
|
modifier ? _bem(namespace.value, getBlock(), '', '', modifier) : '' // bo-button--test
|
|
const be = (blockSuffix?: string, element?: string) =>
|
|
blockSuffix && element
|
|
? _bem(namespace.value, getBlock(), blockSuffix, element, '') // bo-button-test__test
|
|
: ''
|
|
const em = (element?: string, modifier?: string) =>
|
|
element && modifier
|
|
? _bem(namespace.value, getBlock(), '', element, modifier) // bo-button__test--test
|
|
: ''
|
|
const bm = (blockSuffix?: string, modifier?: string) =>
|
|
blockSuffix && modifier
|
|
? _bem(namespace.value, getBlock(), blockSuffix, '', modifier) // bo-button-test--test
|
|
: ''
|
|
const bem = (blockSuffix?: string, element?: string, modifier?: string) =>
|
|
blockSuffix && element && modifier
|
|
? _bem(namespace.value, getBlock(), blockSuffix, element, modifier) // bo-button-test__test--test
|
|
: ''
|
|
const is: {
|
|
(name: string, state: boolean | undefined): string
|
|
(name: string): string
|
|
} = (name: string, ...args: [boolean | undefined] | []) => {
|
|
const state = args.length >= 1 ? args[0]! : true
|
|
return name && state ? `${statePrefix}${name}` : '' // is-test
|
|
}
|
|
|
|
// for css var
|
|
// --bo-xxx: value;
|
|
const cssVar = (object: Record<string, string>) => {
|
|
const styles: Record<string, string> = {}
|
|
for (const key in object) {
|
|
if (object[key]) {
|
|
styles[`--${namespace.value}-${key}`] = object[key] // --bo-test: test
|
|
}
|
|
}
|
|
return styles
|
|
}
|
|
// with block
|
|
const cssVarBlock = (object: Record<string, string>) => {
|
|
const styles: Record<string, string> = {}
|
|
for (const key in object) {
|
|
if (object[key]) {
|
|
styles[`--${namespace.value}-${getBlock()}-${key}`] = object[key] // --bo-button-test: test
|
|
}
|
|
}
|
|
return styles
|
|
}
|
|
|
|
const cssVarName = (name: string) => `--${namespace.value}-${name}` // --bo-test
|
|
const cssVarBlockName = (name: string) => `--${namespace.value}-${getBlock()}-${name}` // --bo-button-test
|
|
|
|
return {
|
|
namespace,
|
|
// bo-button-test
|
|
b,
|
|
e,
|
|
m,
|
|
be,
|
|
em,
|
|
bm,
|
|
bem,
|
|
is,
|
|
// css
|
|
cssVar,
|
|
cssVarName,
|
|
cssVarBlock,
|
|
cssVarBlockName
|
|
}
|
|
}
|
|
|
|
export type UseNamespaceReturn = ReturnType<typeof useNamespace>
|
|
|