(input: string, designSystem: DesignSystem)
| 315 | } |
| 316 | |
| 317 | export function* parseCandidate(input: string, designSystem: DesignSystem): Iterable<Candidate> { |
| 318 | class="cm">// hover:focus:underline |
| 319 | class="cm">// ^^^^^ ^^^^^^ -> Variants |
| 320 | class="cm">// ^^^^^^^^^ -> Base |
| 321 | let rawVariants = segment(input, class="st">':') |
| 322 | |
| 323 | class="cm">// A prefix is a special variant used to prefix all utilities. When present, |
| 324 | class="cm">// all utilities must start with that variant which we will then remove from |
| 325 | class="cm">// the variant list so no other part of the codebase has to know about it. |
| 326 | if (designSystem.theme.prefix) { |
| 327 | if (rawVariants.length === 1) return null |
| 328 | if (rawVariants[0] !== designSystem.theme.prefix) return null |
| 329 | |
| 330 | rawVariants.shift() |
| 331 | } |
| 332 | |
| 333 | class="cm">// Safety: At this point it is safe to use TypeScript's non-null assertion |
| 334 | class="cm">// operator because even if the `input` was an empty string, splitting an |
| 335 | class="cm">// empty string by `:` will always result in an array with at least one |
| 336 | class="cm">// element. |
| 337 | let base = rawVariants.pop()! |
| 338 | |
| 339 | let parsedCandidateVariants: Variant[] = [] |
| 340 | |
| 341 | for (let i = rawVariants.length - 1; i >= 0; --i) { |
| 342 | let parsedVariant = designSystem.parseVariant(rawVariants[i]) |
| 343 | if (parsedVariant === null) return |
| 344 | |
| 345 | parsedCandidateVariants.push(parsedVariant) |
| 346 | } |
| 347 | |
| 348 | let important = false |
| 349 | |
| 350 | class="cm">// Candidates that end with an exclamation mark are the important version with |
| 351 | class="cm">// higher specificity of the non-important candidate, e.g. `mx-4!`. |
| 352 | if (base[base.length - 1] === class="st">'!') { |
| 353 | important = true |
| 354 | base = base.slice(0, -1) |
| 355 | } |
| 356 | |
| 357 | class="cm">// Legacy syntax with leading `!`, e.g. `!mx-4`. |
| 358 | else if (base[0] === class="st">'!') { |
| 359 | important = true |
| 360 | base = base.slice(1) |
| 361 | } |
| 362 | |
| 363 | class="cm">// Check for an exact match of a static utility first as long as it does not |
| 364 | class="cm">// look like an arbitrary value. |
| 365 | if (designSystem.utilities.has(base, class="st">'static') && !base.includes(class="st">'[')) { |
| 366 | yield { |
| 367 | kind: class="st">'static', |
| 368 | root: base, |
| 369 | variants: parsedCandidateVariants, |
| 370 | important, |
| 371 | raw: input, |
| 372 | } |
| 373 | } |
| 374 |
no test coverage detected