import { decl, rule } from './ast'
import { applyVariant } from './compile'
import type { DesignSystem } from './design-system'
interface ClassMetadata {
modifiers: string[]
}
export type ClassEntry = [string, ClassMetadata]
export function getClassList(design: DesignSystem): ClassEntry[] {
let list: [string, ClassMetadata][] = []
for (let utility of design.utilities.keys('static')) {
list.push([utility, { modifiers: [] }])
}
for (let utility of design.utilities.keys('functional')) {
let completions = design.utilities.getCompletions(utility)
for (let group of completions) {
for (let value of group.values) {
let name = value === null ? utility : `${utility}-${value}`
list.push([name, { modifiers: group.modifiers }])
if (group.supportsNegative) {
list.push([`-${name}`, { modifiers: group.modifiers }])
}
}
}
}
list.sort((a, b) => (a[0] === b[0] ? 0 : a[0] < b[0] ? -1 : 1))
return list
}
interface SelectorOptions {
modifier?: string
value?: string
}
export interface VariantEntry {
name: string
isArbitrary: boolean
values: string[]
hasDash: boolean
selectors: (options: SelectorOptions) => string[]
}
export function getVariants(design: DesignSystem) {
let list: VariantEntry[] = []
for (let [root, variant] of design.variants.entries()) {
if (variant.kind === 'arbitrary') continue
let values = design.variants.getCompletions(root)
function selectors({ value, modifier }: SelectorOptions = {}) {
let name = root
if (value) name += `-${value}`
if (modifier) name += `/${modifier}`
let variant = design.parseVariant(name)
if (!variant) return []
let node = rule('.__placeholder__', [decl('color', 'red')])
if (applyVariant(node, variant, design.variants) === null) {
return []
}
let selectors: string[] = []
for (let child of node.nodes) {
if (child.kind === 'rule') {
selectors.push(child.selector)
}
}
return selectors
}
switch (variant.kind) {
case 'static': {
list.push({
name: root,
values,
isArbitrary: false,
hasDash: true,
selectors,
})
break
}
case 'functional': {
list.push({
name: root,
values,
isArbitrary: true,
hasDash: true,
selectors,
})
break
}
case 'compound': {
list.push({
name: root,
values,
isArbitrary: true,
hasDash: true,
selectors,
})
break
}
}
}
return list
}