(input: string, designSystem: DesignSystem)
| 315 | } |
| 316 | |
| 317 | export function* parseCandidate(input: string, designSystem: DesignSystem): Iterable<Candidate> { |
| 318 | // hover:focus:underline |
| 319 | // ^^^^^ ^^^^^^ -> Variants |
| 320 | // ^^^^^^^^^ -> Base |
| 321 | let rawVariants = segment(input, ':') |
| 322 | |
| 323 | // A prefix is a special variant used to prefix all utilities. When present, |
| 324 | // all utilities must start with that variant which we will then remove from |
| 325 | // 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 | // Safety: At this point it is safe to use TypeScript's non-null assertion |
| 334 | // operator because even if the `input` was an empty string, splitting an |
| 335 | // empty string by `:` will always result in an array with at least one |
| 336 | // 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 | // Candidates that end with an exclamation mark are the important version with |
| 351 | // higher specificity of the non-important candidate, e.g. `mx-4!`. |
| 352 | if (base[base.length - 1] === '!') { |
| 353 | important = true |
| 354 | base = base.slice(0, -1) |
| 355 | } |
| 356 | |
| 357 | // Legacy syntax with leading `!`, e.g. `!mx-4`. |
| 358 | else if (base[0] === '!') { |
| 359 | important = true |
| 360 | base = base.slice(1) |
| 361 | } |
| 362 | |
| 363 | // Check for an exact match of a static utility first as long as it does not |
| 364 | // look like an arbitrary value. |
| 365 | if (designSystem.utilities.has(base, 'static') && !base.includes('[')) { |
| 366 | yield { |
| 367 | kind: 'static', |
| 368 | root: base, |
| 369 | variants: parsedCandidateVariants, |
| 370 | important, |
| 371 | raw: input, |
| 372 | } |
| 373 | } |
| 374 |
no test coverage detected