@plumeria/unplugin 18.3.17 → 18.3.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/core.js +67 -37
  2. package/dist/core.mjs +67 -37
  3. package/package.json +2 -2
package/dist/core.js CHANGED
@@ -167,6 +167,46 @@ const foldDynamicVars = (vars) => {
167
167
  return `"${cssVar}": ${value}`;
168
168
  });
169
169
  };
170
+ const isUnitlessProp = (prop) => zss_engine_1.exceptionCamelCase.includes(prop) || prop.startsWith('--');
171
+ const collectVarProps = (style, cssVar, props) => {
172
+ const reference = `var(${cssVar})`;
173
+ for (const [prop, value] of Object.entries(style)) {
174
+ if (typeof value === 'string' && value.includes(reference))
175
+ props.push(prop);
176
+ else if (value !== null && typeof value === 'object')
177
+ collectVarProps(value, cssVar, props);
178
+ }
179
+ };
180
+ const retargetVar = (style, cssVar, next, unitless) => {
181
+ const reference = `var(${cssVar})`;
182
+ for (const [prop, value] of Object.entries(style)) {
183
+ if (typeof value === 'string' && value.includes(reference)) {
184
+ if (isUnitlessProp(prop) === unitless)
185
+ style[prop] = value
186
+ .split(reference)
187
+ .join(`var(${next})`);
188
+ }
189
+ else if (value !== null && typeof value === 'object') {
190
+ retargetVar(value, cssVar, next, unitless);
191
+ }
192
+ }
193
+ };
194
+ const splitVarByUnit = (style, cssVar) => {
195
+ const props = [];
196
+ collectVarProps(style, cssVar, props);
197
+ if (props.length === 0)
198
+ return [];
199
+ const lead = props[0];
200
+ const split = props.find((prop) => isUnitlessProp(prop) !== isUnitlessProp(lead));
201
+ if (!split)
202
+ return [{ cssVar, prop: lead }];
203
+ const splitVar = `${cssVar}-${(0, zss_engine_1.camelToKebabCase)(split).replace(/^-+/, '')}`;
204
+ retargetVar(style, cssVar, splitVar, isUnitlessProp(split));
205
+ return [
206
+ { cssVar, prop: lead },
207
+ { cssVar: splitVar, prop: split },
208
+ ];
209
+ };
170
210
  const applyVarFallback = (style, cssVar, literal) => {
171
211
  const reference = `var(${cssVar})`;
172
212
  for (const [prop, value] of Object.entries(style)) {
@@ -180,18 +220,6 @@ const applyVarFallback = (style, cssVar, literal) => {
180
220
  }
181
221
  }
182
222
  };
183
- const findVarProp = (style, cssVar) => {
184
- for (const [prop, value] of Object.entries(style)) {
185
- if (typeof value === 'string' && value.includes(cssVar))
186
- return prop;
187
- if (value !== null && typeof value === 'object') {
188
- const nested = findVarProp(value, cssVar);
189
- if (nested)
190
- return nested;
191
- }
192
- }
193
- return undefined;
194
- };
195
223
  const unpluginFactory = (options = {}, unpluginMeta) => {
196
224
  const filter = (0, pluginutils_1.createFilter)(options.include, options.exclude);
197
225
  const styleProp = options.styleProp ?? utils_1.DEFAULT_STYLE_PROP;
@@ -1050,47 +1078,49 @@ const unpluginFactory = (options = {}, unpluginMeta) => {
1050
1078
  const style = (0, utils_1.objectExpressionToObject)(func.body, tempStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
1051
1079
  if (!style)
1052
1080
  return null;
1053
- withDefault.forEach(([param, expr]) => {
1081
+ const varGroups = new Map();
1082
+ varParams.forEach((param) => {
1054
1083
  const cssVar = cssVars[param];
1055
- const targetProp = cssVar ? findVarProp(style, cssVar) : undefined;
1056
- if (!targetProp)
1057
- return;
1084
+ if (cssVar)
1085
+ varGroups.set(param, splitVarByUnit(style, cssVar));
1086
+ });
1087
+ withDefault.forEach(([param, expr]) => {
1058
1088
  const literal = expr.type === 'StringLiteral' || expr.type === 'NumericLiteral'
1059
1089
  ? expr.value
1060
1090
  : undefined;
1061
1091
  if (literal === undefined)
1062
1092
  return;
1063
- applyVarFallback(style, cssVar, literal);
1093
+ (varGroups.get(param) ?? []).forEach(({ cssVar }) => applyVarFallback(style, cssVar, literal));
1064
1094
  });
1065
1095
  const vars = [];
1066
1096
  runtime.forEach(({ param, source }) => {
1067
- const cssVar = cssVars[param];
1068
- const targetProp = cssVar ? findVarProp(style, cssVar) : undefined;
1069
- if (!targetProp)
1097
+ const groups = varGroups.get(param);
1098
+ if (!groups?.length)
1070
1099
  return;
1071
1100
  const argStart = source.span.start - baseByteOffset;
1072
1101
  const argEnd = source.span.end - baseByteOffset;
1073
1102
  const argSource = sourceBuffer
1074
1103
  .subarray(argStart, argEnd)
1075
1104
  .toString('utf-8');
1076
- let valueExpr;
1077
- const kebabProp = (0, zss_engine_1.camelToKebabCase)(targetProp);
1078
- const isUnitless = zss_engine_1.exceptionCamelCase.includes(targetProp) ||
1079
- targetProp.startsWith('--');
1080
1105
  const maybeNumber = Number(argSource);
1081
- if (!isNaN(maybeNumber) && argSource.trim() === String(maybeNumber)) {
1082
- valueExpr = JSON.stringify((0, zss_engine_1.applyCssValue)(maybeNumber, kebabProp));
1083
- }
1084
- else if ((argSource.startsWith('"') && argSource.endsWith('"')) ||
1085
- (argSource.startsWith("'") && argSource.endsWith("'"))) {
1086
- valueExpr = JSON.stringify((0, zss_engine_1.applyCssValue)(argSource.slice(1, -1), kebabProp));
1087
- }
1088
- else {
1089
- valueExpr = isUnitless
1090
- ? argSource
1091
- : `(typeof (${argSource}) === 'number' ? (${argSource}) + 'px' : (${argSource}))`;
1092
- }
1093
- vars.push({ cssVar, valueExpr });
1106
+ groups.forEach(({ cssVar, prop }) => {
1107
+ let valueExpr;
1108
+ const kebabProp = (0, zss_engine_1.camelToKebabCase)(prop);
1109
+ if (!isNaN(maybeNumber) &&
1110
+ argSource.trim() === String(maybeNumber)) {
1111
+ valueExpr = JSON.stringify((0, zss_engine_1.applyCssValue)(maybeNumber, kebabProp));
1112
+ }
1113
+ else if ((argSource.startsWith('"') && argSource.endsWith('"')) ||
1114
+ (argSource.startsWith("'") && argSource.endsWith("'"))) {
1115
+ valueExpr = JSON.stringify((0, zss_engine_1.applyCssValue)(argSource.slice(1, -1), kebabProp));
1116
+ }
1117
+ else {
1118
+ valueExpr = isUnitlessProp(prop)
1119
+ ? argSource
1120
+ : `(typeof (${argSource}) === 'number' ? (${argSource}) + 'px' : (${argSource}))`;
1121
+ }
1122
+ vars.push({ cssVar, valueExpr });
1123
+ });
1094
1124
  });
1095
1125
  return { style, vars };
1096
1126
  };
package/dist/core.mjs CHANGED
@@ -131,6 +131,46 @@ const foldDynamicVars = (vars) => {
131
131
  return `"${cssVar}": ${value}`;
132
132
  });
133
133
  };
134
+ const isUnitlessProp = (prop) => exceptionCamelCase.includes(prop) || prop.startsWith('--');
135
+ const collectVarProps = (style, cssVar, props) => {
136
+ const reference = `var(${cssVar})`;
137
+ for (const [prop, value] of Object.entries(style)) {
138
+ if (typeof value === 'string' && value.includes(reference))
139
+ props.push(prop);
140
+ else if (value !== null && typeof value === 'object')
141
+ collectVarProps(value, cssVar, props);
142
+ }
143
+ };
144
+ const retargetVar = (style, cssVar, next, unitless) => {
145
+ const reference = `var(${cssVar})`;
146
+ for (const [prop, value] of Object.entries(style)) {
147
+ if (typeof value === 'string' && value.includes(reference)) {
148
+ if (isUnitlessProp(prop) === unitless)
149
+ style[prop] = value
150
+ .split(reference)
151
+ .join(`var(${next})`);
152
+ }
153
+ else if (value !== null && typeof value === 'object') {
154
+ retargetVar(value, cssVar, next, unitless);
155
+ }
156
+ }
157
+ };
158
+ const splitVarByUnit = (style, cssVar) => {
159
+ const props = [];
160
+ collectVarProps(style, cssVar, props);
161
+ if (props.length === 0)
162
+ return [];
163
+ const lead = props[0];
164
+ const split = props.find((prop) => isUnitlessProp(prop) !== isUnitlessProp(lead));
165
+ if (!split)
166
+ return [{ cssVar, prop: lead }];
167
+ const splitVar = `${cssVar}-${camelToKebabCase(split).replace(/^-+/, '')}`;
168
+ retargetVar(style, cssVar, splitVar, isUnitlessProp(split));
169
+ return [
170
+ { cssVar, prop: lead },
171
+ { cssVar: splitVar, prop: split },
172
+ ];
173
+ };
134
174
  const applyVarFallback = (style, cssVar, literal) => {
135
175
  const reference = `var(${cssVar})`;
136
176
  for (const [prop, value] of Object.entries(style)) {
@@ -144,18 +184,6 @@ const applyVarFallback = (style, cssVar, literal) => {
144
184
  }
145
185
  }
146
186
  };
147
- const findVarProp = (style, cssVar) => {
148
- for (const [prop, value] of Object.entries(style)) {
149
- if (typeof value === 'string' && value.includes(cssVar))
150
- return prop;
151
- if (value !== null && typeof value === 'object') {
152
- const nested = findVarProp(value, cssVar);
153
- if (nested)
154
- return nested;
155
- }
156
- }
157
- return undefined;
158
- };
159
187
  export const unpluginFactory = (options = {}, unpluginMeta) => {
160
188
  const filter = createFilter(options.include, options.exclude);
161
189
  const styleProp = options.styleProp ?? DEFAULT_STYLE_PROP;
@@ -1014,47 +1042,49 @@ export const unpluginFactory = (options = {}, unpluginMeta) => {
1014
1042
  const style = objectExpressionToObject(func.body, tempStaticTable, mergedKeyframesTable, mergedViewTransitionTable, mergedCreateThemeHashTable, scannedTables.createThemeObjectTable, mergedCreateTable, mergedCreateStaticHashTable, scannedTables.createStaticObjectTable, mergedVariantsTable);
1015
1043
  if (!style)
1016
1044
  return null;
1017
- withDefault.forEach(([param, expr]) => {
1045
+ const varGroups = new Map();
1046
+ varParams.forEach((param) => {
1018
1047
  const cssVar = cssVars[param];
1019
- const targetProp = cssVar ? findVarProp(style, cssVar) : undefined;
1020
- if (!targetProp)
1021
- return;
1048
+ if (cssVar)
1049
+ varGroups.set(param, splitVarByUnit(style, cssVar));
1050
+ });
1051
+ withDefault.forEach(([param, expr]) => {
1022
1052
  const literal = expr.type === 'StringLiteral' || expr.type === 'NumericLiteral'
1023
1053
  ? expr.value
1024
1054
  : undefined;
1025
1055
  if (literal === undefined)
1026
1056
  return;
1027
- applyVarFallback(style, cssVar, literal);
1057
+ (varGroups.get(param) ?? []).forEach(({ cssVar }) => applyVarFallback(style, cssVar, literal));
1028
1058
  });
1029
1059
  const vars = [];
1030
1060
  runtime.forEach(({ param, source }) => {
1031
- const cssVar = cssVars[param];
1032
- const targetProp = cssVar ? findVarProp(style, cssVar) : undefined;
1033
- if (!targetProp)
1061
+ const groups = varGroups.get(param);
1062
+ if (!groups?.length)
1034
1063
  return;
1035
1064
  const argStart = source.span.start - baseByteOffset;
1036
1065
  const argEnd = source.span.end - baseByteOffset;
1037
1066
  const argSource = sourceBuffer
1038
1067
  .subarray(argStart, argEnd)
1039
1068
  .toString('utf-8');
1040
- let valueExpr;
1041
- const kebabProp = camelToKebabCase(targetProp);
1042
- const isUnitless = exceptionCamelCase.includes(targetProp) ||
1043
- targetProp.startsWith('--');
1044
1069
  const maybeNumber = Number(argSource);
1045
- if (!isNaN(maybeNumber) && argSource.trim() === String(maybeNumber)) {
1046
- valueExpr = JSON.stringify(applyCssValue(maybeNumber, kebabProp));
1047
- }
1048
- else if ((argSource.startsWith('"') && argSource.endsWith('"')) ||
1049
- (argSource.startsWith("'") && argSource.endsWith("'"))) {
1050
- valueExpr = JSON.stringify(applyCssValue(argSource.slice(1, -1), kebabProp));
1051
- }
1052
- else {
1053
- valueExpr = isUnitless
1054
- ? argSource
1055
- : `(typeof (${argSource}) === 'number' ? (${argSource}) + 'px' : (${argSource}))`;
1056
- }
1057
- vars.push({ cssVar, valueExpr });
1070
+ groups.forEach(({ cssVar, prop }) => {
1071
+ let valueExpr;
1072
+ const kebabProp = camelToKebabCase(prop);
1073
+ if (!isNaN(maybeNumber) &&
1074
+ argSource.trim() === String(maybeNumber)) {
1075
+ valueExpr = JSON.stringify(applyCssValue(maybeNumber, kebabProp));
1076
+ }
1077
+ else if ((argSource.startsWith('"') && argSource.endsWith('"')) ||
1078
+ (argSource.startsWith("'") && argSource.endsWith("'"))) {
1079
+ valueExpr = JSON.stringify(applyCssValue(argSource.slice(1, -1), kebabProp));
1080
+ }
1081
+ else {
1082
+ valueExpr = isUnitlessProp(prop)
1083
+ ? argSource
1084
+ : `(typeof (${argSource}) === 'number' ? (${argSource}) + 'px' : (${argSource}))`;
1085
+ }
1086
+ vars.push({ cssVar, valueExpr });
1087
+ });
1058
1088
  });
1059
1089
  return { style, vars };
1060
1090
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plumeria/unplugin",
3
- "version": "18.3.17",
3
+ "version": "18.3.18",
4
4
  "description": "Universal Plumeria plugin for various build tools",
5
5
  "author": "Refirst 11",
6
6
  "license": "MIT",
@@ -94,7 +94,7 @@
94
94
  "dependencies": {
95
95
  "@rollup/pluginutils": "^5.4.0",
96
96
  "unplugin": "^3.0.0",
97
- "@plumeria/utils": "^18.3.17"
97
+ "@plumeria/utils": "^18.3.18"
98
98
  },
99
99
  "devDependencies": {
100
100
  "@swc/core": "1.15.47",