(design: DesignSystem)
| 154 | } |
| 155 | |
| 156 | export function getVariants(design: DesignSystem) { |
| 157 | let list: VariantEntry[] = [] |
| 158 | |
| 159 | for (let [root, variant] of design.variants.entries()) { |
| 160 | if (variant.kind === 'arbitrary') continue |
| 161 | |
| 162 | let hasDash = root !== '@' |
| 163 | let values = design.variants.getCompletions(root) |
| 164 | |
| 165 | function selectors({ value, modifier }: SelectorOptions = {}) { |
| 166 | let name = root |
| 167 | if (value) name += hasDash ? `-${value}` : value |
| 168 | if (modifier) name += `/${modifier}` |
| 169 | |
| 170 | let variant = design.parseVariant(name) |
| 171 | |
| 172 | if (!variant) return [] |
| 173 | |
| 174 | // Apply the variant to a placeholder rule |
| 175 | let node = styleRule('.__placeholder__', []) |
| 176 | |
| 177 | // If the rule produces no nodes it means the variant does not apply |
| 178 | if (applyVariant(node, variant, design.variants) === null) { |
| 179 | return [] |
| 180 | } |
| 181 | |
| 182 | // Now look at the selector(s) inside the rule |
| 183 | let selectors: string[] = [] |
| 184 | |
| 185 | // Produce v3-style selector strings in the face of nested rules |
| 186 | // this is more visible for things like group-*, not-*, etc… |
| 187 | walk(node.nodes, { |
| 188 | exit(node, ctx) { |
| 189 | if (node.kind !== 'rule' && node.kind !== 'at-rule') return |
| 190 | if (node.nodes.length > 0) return |
| 191 | |
| 192 | let path = ctx.path() |
| 193 | path.push(node) |
| 194 | |
| 195 | // Sort at-rules before style rules |
| 196 | path.sort((a, b) => { |
| 197 | let aIsAtRule = a.kind === 'at-rule' |
| 198 | let bIsAtRule = b.kind === 'at-rule' |
| 199 | |
| 200 | if (aIsAtRule && !bIsAtRule) return -1 |
| 201 | if (!aIsAtRule && bIsAtRule) return 1 |
| 202 | |
| 203 | return 0 |
| 204 | }) |
| 205 | |
| 206 | // A list of the selectors / at rules encountered to get to this point |
| 207 | let group = path.flatMap((node) => { |
| 208 | if (node.kind === 'rule') { |
| 209 | return node.selector === '&' ? [] : [node.selector] |
| 210 | } |
| 211 | |
| 212 | if (node.kind === 'at-rule') { |
| 213 | return [`${node.name} ${node.params}`] |
no test coverage detected