11// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22// SPDX-License-Identifier: Apache-2.0
3- import { mergeInPlace , Override , Theme , ResolveOptions } from '../theme' ;
3+ import { mergeInPlace , Override , Theme } from '../theme' ;
44import { flattenReferenceTokens , collectReferencedTokens } from '../theme/utils' ;
55import type { PropertiesMap , SelectorCustomizer } from './interfaces' ;
66import { RuleCreator } from './rule' ;
@@ -35,35 +35,58 @@ function createMinimalTheme(base: Theme, override: Override): Theme {
3535 return mergeInPlace ( minimalTheme , override ) ;
3636}
3737
38+ function collectAllRequiredTokens (
39+ themes : Theme [ ] ,
40+ initialTokens : string [ ]
41+ ) : { referenceTokens : string [ ] ; referencedTokens : string [ ] } {
42+ const referenceTokens : string [ ] = [ ] ;
43+ themes . forEach ( ( theme ) => referenceTokens . push ( ...Object . keys ( flattenReferenceTokens ( theme ) ) ) ) ;
44+
45+ const alreadyIncluded = new Set ( [ ...initialTokens , ...referenceTokens ] ) ;
46+ const referencedTokens : string [ ] = [ ] ;
47+
48+ themes . forEach ( ( theme ) => {
49+ const referenced = collectReferencedTokens ( theme , [ ...initialTokens , ...referenceTokens ] ) ;
50+ referenced . forEach ( ( token ) => {
51+ if ( ! alreadyIncluded . has ( token ) ) {
52+ referencedTokens . push ( token ) ;
53+ alreadyIncluded . add ( token ) ;
54+ }
55+ } ) ;
56+ } ) ;
57+
58+ return { referenceTokens, referencedTokens } ;
59+ }
60+
61+ function addMissingTokensToTheme ( theme : Theme , tokens : string [ ] , sourceTheme : Theme ) : void {
62+ tokens . forEach ( ( token ) => {
63+ if ( ! ( token in theme . tokens ) && token in sourceTheme . tokens ) {
64+ theme . tokens [ token ] = sourceTheme . tokens [ token ] ;
65+ }
66+ } ) ;
67+ }
68+
3869export function createOverrideDeclarations (
3970 base : Theme ,
4071 override : Override ,
4172 propertiesMap : PropertiesMap ,
4273 selectorCustomizer : SelectorCustomizer
4374) : string {
4475 const minimalTheme = createMinimalTheme ( base , override ) ;
45- let usedTokens = Object . keys ( minimalTheme . tokens ) ;
46-
47- const allReferencedTokens = collectReferencedTokens ( base , usedTokens ) ;
48- usedTokens = [ ...usedTokens , ...allReferencedTokens ] ;
76+ const initialTokens = Object . keys ( minimalTheme . tokens ) ;
4977
78+ const { referencedTokens } = collectAllRequiredTokens ( [ base ] , initialTokens ) ;
5079 // Add referenced tokens to minimalTheme so they get output in root
5180 // The transformer will remove them from mode/context selectors since they're unchanged
52- allReferencedTokens . forEach ( ( token ) => {
53- if ( ! ( token in minimalTheme . tokens ) && token in base . tokens ) {
54- minimalTheme . tokens [ token ] = base . tokens [ token ] ;
55- }
56- } ) ;
81+ addMissingTokensToTheme ( minimalTheme , referencedTokens , base ) ;
5782
83+ const usedTokens = [ ...initialTokens , ...referencedTokens ] ;
5884 const ruleCreator = new RuleCreator (
5985 new Selector ( selectorCustomizer ) ,
6086 new UsedPropertyRegistry ( propertiesMap , usedTokens )
6187 ) ;
62- const stylesheetCreator = new SingleThemeCreator ( minimalTheme , ruleCreator , base , { propertiesMap } ) ;
63- const stylesheet = stylesheetCreator . create ( ) ;
64- const transformer = new MinimalTransformer ( ) ;
65- const minimal = transformer . transform ( stylesheet ) ;
66- return minimal . toString ( ) ;
88+ const stylesheet = new SingleThemeCreator ( minimalTheme , ruleCreator , base , propertiesMap ) . create ( ) ;
89+ return new MinimalTransformer ( ) . transform ( stylesheet ) . toString ( ) ;
6790}
6891
6992export function createBuildDeclarations (
@@ -74,38 +97,13 @@ export function createBuildDeclarations(
7497 used : string [ ]
7598) : string {
7699 const themes = [ primary , ...secondary ] ;
77- // Add reference tokens (from referenceTokens object)
78- const allReferenceTokens : string [ ] = [ ] ;
79- themes . forEach ( ( theme : Theme ) => {
80- const referenceTokens = flattenReferenceTokens ( theme ) ;
81- allReferenceTokens . push ( ...Object . keys ( referenceTokens ) ) ;
82- } ) ;
83-
84- // Collect referenced leaf tokens (like colorWhite, colorGreyOpaque70)
85- const allReferencedTokens : string [ ] = [ ] ;
86- const alreadyIncluded = new Set ( [ ...used , ...allReferenceTokens ] ) ;
87-
88- themes . forEach ( ( theme : Theme ) => {
89- const referenced = collectReferencedTokens ( theme , [ ...used , ...allReferenceTokens ] ) ;
90- referenced . forEach ( ( token ) => {
91- if ( ! alreadyIncluded . has ( token ) ) {
92- allReferencedTokens . push ( token ) ;
93- alreadyIncluded . add ( token ) ;
94- }
95- } ) ;
96- } ) ;
97-
98- // Add allReferencedTokens to effectiveUsed so they get created in primary rule
99- // The transformer will remove them from mode rules since they're unchanged
100- const effectiveUsed = [ ...used , ...allReferenceTokens , ...allReferencedTokens ] ;
100+ const { referenceTokens, referencedTokens } = collectAllRequiredTokens ( themes , used ) ;
101+ const usedTokens = [ ...used , ...referenceTokens , ...referencedTokens ] ;
101102
102103 const ruleCreator = new RuleCreator (
103104 new Selector ( selectorCustomizer ) ,
104- new UsedPropertyRegistry ( propertiesMap , effectiveUsed )
105+ new UsedPropertyRegistry ( propertiesMap , usedTokens )
105106 ) ;
106- const stylesheetCreator = new MultiThemeCreator ( [ primary , ...secondary ] , ruleCreator , { propertiesMap } ) ;
107- const stylesheet = stylesheetCreator . create ( ) ;
108- const transformer = new MinimalTransformer ( ) ;
109- const minimal = transformer . transform ( stylesheet ) ;
110- return minimal . toString ( ) ;
107+ const stylesheet = new MultiThemeCreator ( themes , ruleCreator , propertiesMap ) . create ( ) ;
108+ return new MinimalTransformer ( ) . transform ( stylesheet ) . toString ( ) ;
111109}
0 commit comments