@@ -39,6 +39,7 @@ namespace margelo::nitro::cssnitro {
3939 * So we use an unordered_map and convert it to AnyMap at the end.
4040 */
4141 std::unordered_map<std::string, AnyValue> mergedStyles;
42+ std::unordered_map<std::string, AnyValue> mergedProps;
4243
4344 // Collect all style rules from all classNames
4445 std::vector<HybridStyleRule> allStyleRules;
@@ -81,34 +82,89 @@ namespace margelo::nitro::cssnitro {
8182 }
8283
8384 if (styleRule.d .has_value ()) {
84- const auto declarations = styleRule.d .value ();
85- const auto &dStyles = std::get<0 >(std::get<0 >(declarations));
86- for (const auto &kv: dStyles->getMap ()) {
87- // Only set if key doesn't already exist
88- if (mergedStyles.count (kv.first ) == 0 ) {
89- // if kv.second is an array with "fn" as the first key, resolve it
90- if (dStyles->isArray (kv.first )) {
91- const auto &arr = dStyles->getArray (kv.first );
92- if (!arr.empty () &&
93- std::holds_alternative<std::string>(arr[0 ]) &&
94- std::get<std::string>(arr[0 ]) == " fn" ) {
95- auto result = StyleFunction::resolveStyleFn (
96- arr, get, variableScope);
97-
98- // Skip if resolveStyleFn returns nullptr
99- if (std::holds_alternative<std::monostate>(
100- result)) {
101- continue ;
85+ const auto &declarations = styleRule.d .value ();
86+
87+ // declarations is a variant that can hold either:
88+ // - tuple with 1 item (single declaration)
89+ // - tuple with 2 items (multiple declarations)
90+ // We use std::visit to safely access it
91+ std::visit ([&mergedStyles, &mergedProps, &get, &variableScope](
92+ const auto &decl) {
93+ // decl is a tuple, get the first element (the styles)
94+ const auto &dStyles = std::get<0 >(decl);
95+
96+ // Check if dStyles is valid before accessing
97+ if (dStyles) {
98+ for (const auto &kv: dStyles->getMap ()) {
99+ // Only set if key doesn't already exist
100+ if (mergedStyles.count (kv.first ) == 0 ) {
101+ // if kv.second is an array with "fn" as the first key, resolve it
102+ if (dStyles->isArray (kv.first )) {
103+ const auto &arr = dStyles->getArray (kv.first );
104+ if (!arr.empty () &&
105+ std::holds_alternative<std::string>(
106+ arr[0 ]) &&
107+ std::get<std::string>(arr[0 ]) == " fn" ) {
108+ auto result = StyleFunction::resolveStyleFn (
109+ arr, get, variableScope);
110+
111+ // Skip if resolveStyleFn returns nullptr
112+ if (std::holds_alternative<std::monostate>(
113+ result)) {
114+ return ;
115+ }
116+
117+ mergedStyles[kv.first ] = result;
118+ return ;
119+ }
102120 }
121+ mergedStyles[kv.first ] = kv.second ;
122+ }
123+ }
124+ }
103125
104- mergedStyles[kv.first ] = result;
105- continue ;
126+ // Check if there's a second element in the tuple (props)
127+ if constexpr (std::tuple_size<std::decay_t <decltype (decl)>>::value >
128+ 1 ) {
129+ const auto &dPropsOpt = std::get<1 >(decl);
130+
131+ // dPropsOpt is optional, check if it has a value
132+ if (dPropsOpt.has_value ()) {
133+ const auto &dProps = dPropsOpt.value ();
134+
135+ // Check if dProps is valid before accessing
136+ if (dProps) {
137+ for (const auto &kv: dProps->getMap ()) {
138+ // Only set if key doesn't already exist
139+ if (mergedProps.count (kv.first ) == 0 ) {
140+ // if kv.second is an array with "fn" as the first key, resolve it
141+ if (dProps->isArray (kv.first )) {
142+ const auto &arr = dProps->getArray (
143+ kv.first );
144+ if (!arr.empty () &&
145+ std::holds_alternative<std::string>(
146+ arr[0 ]) &&
147+ std::get<std::string>(arr[0 ]) == " fn" ) {
148+ auto result = StyleFunction::resolveStyleFn (
149+ arr, get, variableScope);
150+
151+ // Skip if resolveStyleFn returns nullptr
152+ if (std::holds_alternative<std::monostate>(
153+ result)) {
154+ continue ;
155+ }
156+
157+ mergedProps[kv.first ] = result;
158+ continue ;
159+ }
160+ }
161+ mergedProps[kv.first ] = kv.second ;
162+ }
163+ }
106164 }
107165 }
108- mergedStyles[kv.first ] = kv.second ;
109166 }
110- }
111- // Ignore the other entries for now
167+ }, declarations);
112168 }
113169 }
114170
@@ -126,19 +182,21 @@ namespace margelo::nitro::cssnitro {
126182
127183 for (const auto &kv: mergedStyles) {
128184 if (transformProps.count (kv.first ) > 0 ) {
129- if (!anyMap->contains (" transform" )) {
130- anyMap->setArray (" transform" , AnyArray{});
131- }
185+ AnyArray transformArray;
132186
133- auto transformArray = anyMap->getArray (" transform" );
187+ // Get existing transform array if it exists
188+ if (anyMap->contains (" transform" )) {
189+ transformArray = anyMap->getArray (" transform" );
190+ }
134191
135192 // find the value in the array with the key matching kv.first and set it to kv.second
136193 bool foundTransform = false ;
137- for (auto &item: transformArray) {
138- if (std::holds_alternative<AnyObject>(item )) {
139- auto & obj = std::get<AnyObject>(item );
194+ for (size_t i = 0 ; i < transformArray. size (); i++ ) {
195+ if (std::holds_alternative<AnyObject>(transformArray[i] )) {
196+ auto obj = std::get<AnyObject>(transformArray[i] );
140197 if (obj.count (kv.first ) > 0 ) {
141198 obj[kv.first ] = kv.second ;
199+ transformArray[i] = obj;
142200 foundTransform = true ;
143201 break ;
144202 }
@@ -161,6 +219,16 @@ namespace margelo::nitro::cssnitro {
161219 next.style = anyMap;
162220 }
163221
222+ // Convert mergedProps to AnyMap and set next.props
223+ if (!mergedProps.empty ()) {
224+ auto anyMap = AnyMap::make (mergedProps.size ());
225+
226+ for (const auto &kv: mergedProps) {
227+ anyMap->setAny (kv.first , kv.second );
228+ }
229+ next.props = anyMap;
230+ }
231+
164232 if (shouldRerender (next)) {
165233 (void ) rerender ();
166234 }
0 commit comments