@plumeria/unplugin 18.3.16 → 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 +71 -41
  2. package/dist/core.mjs +71 -41
  3. package/package.json +2 -2
package/dist/core.js CHANGED
@@ -167,30 +167,58 @@ const foldDynamicVars = (vars) => {
167
167
  return `"${cssVar}": ${value}`;
168
168
  });
169
169
  };
170
- const replaceVarValue = (style, cssVar, next) => {
170
+ const isUnitlessProp = (prop) => zss_engine_1.exceptionCamelCase.includes(prop) || prop.startsWith('--');
171
+ const collectVarProps = (style, cssVar, props) => {
172
+ const reference = `var(${cssVar})`;
171
173
  for (const [prop, value] of Object.entries(style)) {
172
- if (typeof value === 'string' && value.includes(cssVar)) {
173
- style[prop] = next;
174
- return true;
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})`);
175
188
  }
176
- if (value !== null && typeof value === 'object') {
177
- if (replaceVarValue(value, cssVar, next))
178
- return true;
189
+ else if (value !== null && typeof value === 'object') {
190
+ retargetVar(value, cssVar, next, unitless);
179
191
  }
180
192
  }
181
- return false;
182
193
  };
183
- const findVarProp = (style, cssVar) => {
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
+ };
210
+ const applyVarFallback = (style, cssVar, literal) => {
211
+ const reference = `var(${cssVar})`;
184
212
  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;
213
+ if (typeof value === 'string' && value.includes(reference)) {
214
+ style[prop] = value
215
+ .split(reference)
216
+ .join(`var(${cssVar}, ${(0, zss_engine_1.applyCssValue)(literal, (0, zss_engine_1.camelToKebabCase)(prop))})`);
217
+ }
218
+ else if (value !== null && typeof value === 'object') {
219
+ applyVarFallback(value, cssVar, literal);
191
220
  }
192
221
  }
193
- return undefined;
194
222
  };
195
223
  const unpluginFactory = (options = {}, unpluginMeta) => {
196
224
  const filter = (0, pluginutils_1.createFilter)(options.include, options.exclude);
@@ -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
- replaceVarValue(style, cssVar, `var(${cssVar}, ${(0, zss_engine_1.applyCssValue)(literal, (0, zss_engine_1.camelToKebabCase)(targetProp))})`);
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,30 +131,58 @@ const foldDynamicVars = (vars) => {
131
131
  return `"${cssVar}": ${value}`;
132
132
  });
133
133
  };
134
- const replaceVarValue = (style, cssVar, next) => {
134
+ const isUnitlessProp = (prop) => exceptionCamelCase.includes(prop) || prop.startsWith('--');
135
+ const collectVarProps = (style, cssVar, props) => {
136
+ const reference = `var(${cssVar})`;
135
137
  for (const [prop, value] of Object.entries(style)) {
136
- if (typeof value === 'string' && value.includes(cssVar)) {
137
- style[prop] = next;
138
- return true;
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})`);
139
152
  }
140
- if (value !== null && typeof value === 'object') {
141
- if (replaceVarValue(value, cssVar, next))
142
- return true;
153
+ else if (value !== null && typeof value === 'object') {
154
+ retargetVar(value, cssVar, next, unitless);
143
155
  }
144
156
  }
145
- return false;
146
157
  };
147
- const findVarProp = (style, cssVar) => {
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
+ };
174
+ const applyVarFallback = (style, cssVar, literal) => {
175
+ const reference = `var(${cssVar})`;
148
176
  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;
177
+ if (typeof value === 'string' && value.includes(reference)) {
178
+ style[prop] = value
179
+ .split(reference)
180
+ .join(`var(${cssVar}, ${applyCssValue(literal, camelToKebabCase(prop))})`);
181
+ }
182
+ else if (value !== null && typeof value === 'object') {
183
+ applyVarFallback(value, cssVar, literal);
155
184
  }
156
185
  }
157
- return undefined;
158
186
  };
159
187
  export const unpluginFactory = (options = {}, unpluginMeta) => {
160
188
  const filter = createFilter(options.include, options.exclude);
@@ -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
- replaceVarValue(style, cssVar, `var(${cssVar}, ${applyCssValue(literal, camelToKebabCase(targetProp))})`);
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.16",
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.16"
97
+ "@plumeria/utils": "^18.3.18"
98
98
  },
99
99
  "devDependencies": {
100
100
  "@swc/core": "1.15.47",