Blame view

天文台pc/tianwentai-ui/node_modules/tailwind-merge/src/lib/parse-class-name.ts 3.7 KB
bc518174   王天杨   提交两个项目文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
  import { AnyConfig, ParsedClassName } from './types'
  
  export const IMPORTANT_MODIFIER = '!'
  const MODIFIER_SEPARATOR = ':'
  const MODIFIER_SEPARATOR_LENGTH = MODIFIER_SEPARATOR.length
  
  export const createParseClassName = (config: AnyConfig) => {
      const { prefix, experimentalParseClassName } = config
  
      /**
       * Parse class name into parts.
       *
       * Inspired by `splitAtTopLevelOnly` used in Tailwind CSS
       * @see https://github.com/tailwindlabs/tailwindcss/blob/v3.2.2/src/util/splitAtTopLevelOnly.js
       */
      let parseClassName = (className: string): ParsedClassName => {
          const modifiers = []
  
          let bracketDepth = 0
          let parenDepth = 0
          let modifierStart = 0
          let postfixModifierPosition: number | undefined
  
          for (let index = 0; index < className.length; index++) {
              let currentCharacter = className[index]
  
              if (bracketDepth === 0 && parenDepth === 0) {
                  if (currentCharacter === MODIFIER_SEPARATOR) {
                      modifiers.push(className.slice(modifierStart, index))
                      modifierStart = index + MODIFIER_SEPARATOR_LENGTH
                      continue
                  }
  
                  if (currentCharacter === '/') {
                      postfixModifierPosition = index
                      continue
                  }
              }
  
              if (currentCharacter === '[') {
                  bracketDepth++
              } else if (currentCharacter === ']') {
                  bracketDepth--
              } else if (currentCharacter === '(') {
                  parenDepth++
              } else if (currentCharacter === ')') {
                  parenDepth--
              }
          }
  
          const baseClassNameWithImportantModifier =
              modifiers.length === 0 ? className : className.substring(modifierStart)
          const baseClassName = stripImportantModifier(baseClassNameWithImportantModifier)
          const hasImportantModifier = baseClassName !== baseClassNameWithImportantModifier
          const maybePostfixModifierPosition =
              postfixModifierPosition && postfixModifierPosition > modifierStart
                  ? postfixModifierPosition - modifierStart
                  : undefined
  
          return {
              modifiers,
              hasImportantModifier,
              baseClassName,
              maybePostfixModifierPosition,
          }
      }
  
      if (prefix) {
          const fullPrefix = prefix + MODIFIER_SEPARATOR
          const parseClassNameOriginal = parseClassName
          parseClassName = (className) =>
              className.startsWith(fullPrefix)
                  ? parseClassNameOriginal(className.substring(fullPrefix.length))
                  : {
                        isExternal: true,
                        modifiers: [],
                        hasImportantModifier: false,
                        baseClassName: className,
                        maybePostfixModifierPosition: undefined,
                    }
      }
  
      if (experimentalParseClassName) {
          const parseClassNameOriginal = parseClassName
          parseClassName = (className) =>
              experimentalParseClassName({ className, parseClassName: parseClassNameOriginal })
      }
  
      return parseClassName
  }
  
  const stripImportantModifier = (baseClassName: string) => {
      if (baseClassName.endsWith(IMPORTANT_MODIFIER)) {
          return baseClassName.substring(0, baseClassName.length - 1)
      }
  
      /**
       * In Tailwind CSS v3 the important modifier was at the start of the base class name. This is still supported for legacy reasons.
       * @see https://github.com/dcastil/tailwind-merge/issues/513#issuecomment-2614029864
       */
      if (baseClassName.startsWith(IMPORTANT_MODIFIER)) {
          return baseClassName.substring(1)
      }
  
      return baseClassName
  }