import type { CSSEntries , CSSObject , DynamicMatcher , ParsedColorValue , RuleContext } from '@unocss/core' ; import { hex2rgba } from '@unocss/core' ; import type { Theme } from '../theme' ; import { handler as h } from './handlers' ; import { directionMap } from './mappings' ; /**
 * Provide  DynamicMatcher function returning spacing definition. See spacing rules.
 *
 *  param { string } propertyPrefix return { DynamicMatcher } DynamicMatcher see directionMap export const directionSize = ( propertyPrefix ) : DynamicMatcher => ( [ _ , direction , size ] ) : CSSEntries | undefined => { const v = h . bracket . cssvar . auto . fraction . rem ( size ) ; if ( v !== undefined ) return directionMap [ direction ] . map ( i => [ `${ propertyPrefix }${ i }` , v ] ) ; } ; /**
 * Obtain color from theme by camel-casing colors.
 */ const getThemeColor = ( theme , colors ) => theme . colors ?. [ colors . join ( '-' ) . replace ( /(-[a-z])/g , n => n . slice ( 1 ) . toUpperCase ( ) ) ] ; example param { string } body param { Theme } theme -  Theme object.
 *  return { ParsedColorValue | undefined } ParsedColorValue object if string is parseable.
  export const parseColor = ( body , theme ) : ParsedColorValue | undefined => { const [ main , opacity ] = body . split ( /(?:\/|:)/ ) ; const colors = main . replace ( /([a-z])([0-9])/g , '$1-$2' ) . split ( /-/g ) ; const [ name ] = colors ; if ( ! name ) return ; let color ; const bracket = h . bracket ( main ) ; const bracketOrMain = bracket || main ; if ( bracketOrMain . startsWith ( '#' ) ) color = bracketOrMain . slice ( 1 ) ; else if ( bracketOrMain . startsWith ( 'hex-' ) ) color = bracketOrMain . slice ( 4 ) ; else if ( main . startsWith ( '$' ) ) color = h . cssvar ( main ) ; color = color || bracket ; let no = 'DEFAULT' ; if ( ! color ) { let colorData ; const [ scale ] = colors . slice ( - 1 ) ; if ( scale . match ( /^\d+$/ ) ) { no = scale ; colorData = getThemeColor ( theme , colors . slice ( 0 , - 1 ) ) ; } else { colorData = getThemeColor ( theme , colors ) ; if ( ! colorData ) { [ , no = no ] = colors ; colorData = getThemeColor ( theme , [ name ] ) ; } } if ( typeof colorData === 'string' ) color = colorData ; else if ( no && colorData ) color = colorData [ no ] ; } const rgba = hex2rgba ( color ) ; const alpha = opacity ? opacity [ 0 ] === '[' ? h . bracket . percent ( opacity ) ! : ( parseFloat ( opacity ) / 100 ) : rgba ?. [ 3 ] ; const hasAlpha = alpha != null && ! Number . isNaN ( alpha ) ; if ( rgba ) { if ( hasAlpha ) { rgba [ 3 ] = typeof alpha === 'string' && ! alpha . includes ( '%' ) ? parseFloat ( alpha ) : alpha as number ; } else { rgba . splice ( 3 ) ; } } return { opacity , name , no , color , rgba , alpha : hasAlpha ? alpha : undefined , } ; } ; /**
 * Provide  DynamicMatcher function to produce color value matched from rule.
 *
 *  see parseColor example example example example param { string } property param { string } varName return { DynamicMatcher } DynamicMatcher object.
  export const colorResolver = ( property , varName ) : DynamicMatcher => ( [ , body ] , { theme } ) : CSSObject | undefined => { const data = parseColor ( body , theme ) ; if ( ! data ) return ; const { alpha , opacity , color , rgba } = data ; if ( ! color ) return ; if ( rgba ) { if ( alpha != null ) { return { [ property ] : `rgba(${ rgba . join ( ',' ) })` , } ; } else { return { [ `--un-${ varName }-opacity` ] : ( opacity && h . cssvar ( opacity ) ) ?? 1 , [ property ] : `rgba(${ rgba . join ( ',' ) },var(--un-${ varName }-opacity))` , } ; } } else { return { [ property ] : color . replace ( '%alpha' , `${ alpha || 1 }` ) , } ; } } ;