import type * as Style from './index.js' import * as TypeDefinitions from './types/index.js' import type { GroupBy } from '../utils/typescript.js' import type { Unformatted } from '../utils/value.js' export type TypeDefinitionsByCategory = GroupBy<(typeof TypeDefinitions)[keyof typeof TypeDefinitions], 'category'> export type TypeDefinitionGeneric< Props, T extends Style.Type, Category extends 'basic' | 'aspect' | 'element' | 'concept' > = { Props: (props: Unformatted) => Props validate: (props: Props) => boolean fix: (props: Props, styles: Style.Rule[]) => Props type: T category: Category label: string forms?: T extends Style.Type.ElementAspect | Style.Type.Basic ? Style.Form[] : never aspects?: T extends Style.Type.Element ? readonly Style.Type.Aspect[] : never summarize?: (props: Props, styles?: Style.Rule[], form?: string) => string } TypeDefinitions satisfies { [key in keyof typeof TypeDefinitions]: TypeDefinitionGeneric< ReturnType<(typeof TypeDefinitions)[key]['Props']>, key, (typeof TypeDefinitions)[key]['category'] > } export { TypeDefinitions } export type TypesByCategory = { [key in keyof TypeDefinitionsByCategory]: TypeDefinitionsByCategory[key]['type'] } export type Category = keyof TypesByCategory export type TypeDefinition = (typeof TypeDefinitions)[T] export type TypeDefinitionCategory = TypeDefinitionsByCategory[T] export function isTypeInCategory(type: Style.Type, category: C): type is TypesByCategory[C] { return TypeDefinitions[type].category == category } export function isTypeElementAspect(type: Style.Type): type is Style.Type.ElementAspect { for (var property in TypeDefinitions) { const def = TypeDefinitions[property as keyof typeof TypeDefinitions] if ('aspects' in def && def.aspects.some((t) => t == type)) return true } return false } export function getAspects(type: T) { const definition = TypeDefinitions[type] if (definition.category == 'element') { return definition.aspects as unknown as Style.Type.ElementAspect[] } return [] as unknown as Style.Type.ElementAspect[] } export function getForms(type: T) { const definition = TypeDefinitions[type] if ('forms' in definition) { return definition.forms } return [] as Style.Form[] }