(
value: PropertyValueDefinition<P>,
parentPriority: number,
currentConditions: Set<string>,
skipConditions: Set<string>,
fn: (
value: P,
priority: number,
conditions: Set<string>,
skipConditions: Set<string>
) => [number, Rule[]]
)
| 539 | } |
| 540 | |
| 541 | function conditionalToRules<P extends CustomValue | any[]>( |
| 542 | value: PropertyValueDefinition<P>, |
| 543 | parentPriority: number, |
| 544 | currentConditions: Set<string>, |
| 545 | skipConditions: Set<string>, |
| 546 | fn: ( |
| 547 | value: P, |
| 548 | priority: number, |
| 549 | conditions: Set<string>, |
| 550 | skipConditions: Set<string> |
| 551 | ) => [number, Rule[]] |
| 552 | ): [number, Rule[]] { |
| 553 | if (value && typeof value === 'object' && !Array.isArray(value)) { |
| 554 | let rules: Rule[] = []; |
| 555 | |
| 556 | // Later conditions in parent rules override conditions in child rules. |
| 557 | let subSkipConditions = new Set([...skipConditions, ...Object.keys(value)]); |
| 558 | |
| 559 | // Skip the default condition if we're already filtering by one of the other possible conditions. |
| 560 | // For example, if someone specifies `dark: 'gray-400'`, only include the dark version of `gray-400` from the theme. |
| 561 | let skipDefault = Object.keys(value).some(k => currentConditions.has(k)); |
| 562 | let wasCSSCondition = false; |
| 563 | let priority = parentPriority; |
| 564 | |
| 565 | for (let condition in value) { |
| 566 | if (skipConditions.has(condition) || (condition === 'default' && skipDefault)) { |
| 567 | continue; |
| 568 | } |
| 569 | subSkipConditions.delete(condition); |
| 570 | |
| 571 | let val = value[condition]; |
| 572 | |
| 573 | // If a theme condition comes after runtime conditions, create a new grouping. |
| 574 | // This makes the CSS class unconditional so it appears outside the `else` block in the JS. |
| 575 | // The @layer order in the generated CSS will ensure that it overrides classes applied by runtime conditions. |
| 576 | let isCSSCondition = condition in theme.conditions || /^[@:]/.test(condition); |
| 577 | if (!wasCSSCondition && isCSSCondition && rules.length) { |
| 578 | rules = [new GroupRule(rules)]; |
| 579 | } |
| 580 | wasCSSCondition = isCSSCondition; |
| 581 | |
| 582 | // Increment the current priority whenever we see a new CSS condition. |
| 583 | if (isCSSCondition) { |
| 584 | priority++; |
| 585 | } |
| 586 | |
| 587 | // If this is a runtime condition, inherit the priority from the parent rule. |
| 588 | // Otherwise, use the current maximum of the parent and current priorities. |
| 589 | let rulePriority = isCSSCondition ? priority : parentPriority; |
| 590 | |
| 591 | if ( |
| 592 | condition === 'default' || |
| 593 | isCSSCondition || |
| 594 | /^is[A-Z]/.test(condition) || |
| 595 | /^allows[A-Z]/.test(condition) |
| 596 | ) { |
| 597 | let subConditions = currentConditions; |
| 598 | if (isCSSCondition) { |
no test coverage detected