index.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. import { computed, getCurrentInstance, inject, ref, unref } from 'vue'
  2. import type { InjectionKey, Ref } from 'vue'
  3. export const defaultNamespace = 'el'
  4. const statePrefix = 'is-'
  5. const _bem = (
  6. namespace: string,
  7. block: string,
  8. blockSuffix: string,
  9. element: string,
  10. modifier: string
  11. ) => {
  12. let cls = `${namespace}-${block}`
  13. if (blockSuffix) {
  14. cls += `-${blockSuffix}`
  15. }
  16. if (element) {
  17. cls += `__${element}`
  18. }
  19. if (modifier) {
  20. cls += `--${modifier}`
  21. }
  22. return cls
  23. }
  24. export const namespaceContextKey: InjectionKey<Ref<string | undefined>> =
  25. Symbol('namespaceContextKey')
  26. export const useGetDerivedNamespace = (
  27. namespaceOverrides?: Ref<string | undefined>
  28. ) => {
  29. const derivedNamespace =
  30. namespaceOverrides ||
  31. (getCurrentInstance()
  32. ? inject(namespaceContextKey, ref(defaultNamespace))
  33. : ref(defaultNamespace))
  34. const namespace = computed(() => {
  35. return unref(derivedNamespace) || defaultNamespace
  36. })
  37. return namespace
  38. }
  39. export const useNamespace = (
  40. block: string,
  41. namespaceOverrides?: Ref<string | undefined>
  42. ) => {
  43. const namespace = useGetDerivedNamespace(namespaceOverrides)
  44. const b = (blockSuffix = '') =>
  45. _bem(namespace.value, block, blockSuffix, '', '')
  46. const e = (element?: string) =>
  47. element ? _bem(namespace.value, block, '', element, '') : ''
  48. const m = (modifier?: string) =>
  49. modifier ? _bem(namespace.value, block, '', '', modifier) : ''
  50. const be = (blockSuffix?: string, element?: string) =>
  51. blockSuffix && element
  52. ? _bem(namespace.value, block, blockSuffix, element, '')
  53. : ''
  54. const em = (element?: string, modifier?: string) =>
  55. element && modifier
  56. ? _bem(namespace.value, block, '', element, modifier)
  57. : ''
  58. const bm = (blockSuffix?: string, modifier?: string) =>
  59. blockSuffix && modifier
  60. ? _bem(namespace.value, block, blockSuffix, '', modifier)
  61. : ''
  62. const bem = (blockSuffix?: string, element?: string, modifier?: string) =>
  63. blockSuffix && element && modifier
  64. ? _bem(namespace.value, block, blockSuffix, element, modifier)
  65. : ''
  66. const is: {
  67. (name: string, state: boolean | undefined): string
  68. (name: string): string
  69. } = (name: string, ...args: [boolean | undefined] | []) => {
  70. const state = args.length >= 1 ? args[0]! : true
  71. return name && state ? `${statePrefix}${name}` : ''
  72. }
  73. // for css var
  74. // --el-xxx: value;
  75. const cssVar = (object: Record<string, string>) => {
  76. const styles: Record<string, string> = {}
  77. for (const key in object) {
  78. if (object[key]) {
  79. styles[`--${namespace.value}-${key}`] = object[key]
  80. }
  81. }
  82. return styles
  83. }
  84. // with block
  85. const cssVarBlock = (object: Record<string, string>) => {
  86. const styles: Record<string, string> = {}
  87. for (const key in object) {
  88. if (object[key]) {
  89. styles[`--${namespace.value}-${block}-${key}`] = object[key]
  90. }
  91. }
  92. return styles
  93. }
  94. const cssVarName = (name: string) => `--${namespace.value}-${name}`
  95. const cssVarBlockName = (name: string) =>
  96. `--${namespace.value}-${block}-${name}`
  97. return {
  98. namespace,
  99. b,
  100. e,
  101. m,
  102. be,
  103. em,
  104. bm,
  105. bem,
  106. is,
  107. // css
  108. cssVar,
  109. cssVarName,
  110. cssVarBlock,
  111. cssVarBlockName,
  112. }
  113. }
  114. export type UseNamespaceReturn = ReturnType<typeof useNamespace>