@plumeria/utils 19.2.1 → 19.2.3

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.
@@ -14,11 +14,18 @@ export type StyleFunction = {
14
14
  export type StyleFunctions = Record<string, StyleFunction>;
15
15
  export declare const styleFunctionsOf: (objExpr: ObjectExpression) => StyleFunctions;
16
16
  export declare const isUnitlessProp: (prop: string) => boolean;
17
- export declare const splitVarByUnit: (style: CSSObject, cssVar: string) => Array<{
17
+ type VarUnit = {
18
+ unit: string;
19
+ written: boolean;
20
+ };
21
+ type VarGroup = {
18
22
  cssVar: string;
19
23
  prop: string;
20
- }>;
21
- export declare const applyVarFallback: (style: CSSObject, cssVar: string, literal: string | number) => void;
24
+ unit: string;
25
+ written: boolean;
26
+ };
27
+ export declare const splitVarByUnit: (style: CSSObject, cssVar: string) => VarGroup[];
28
+ export declare const applyVarFallback: (style: CSSObject, cssVar: string, literal: string | number, unit: VarUnit) => void;
22
29
  export type DynamicStyleTables = {
23
30
  keyframesHashTable: KeyframesHashTable;
24
31
  viewTransitionHashTable: ViewTransitionHashTable;
@@ -33,6 +40,9 @@ export type DynamicStyleResult = {
33
40
  varGroups: Map<string, Array<{
34
41
  cssVar: string;
35
42
  prop: string;
43
+ unit: string;
44
+ written: boolean;
36
45
  }>>;
37
46
  };
38
47
  export declare const resolveDynamicStyle: (func: StyleFunction, runtimeParams: string[], staticTable: StaticTable, tables: DynamicStyleTables, providedParams?: ReadonlySet<string>) => DynamicStyleResult;
48
+ export {};
@@ -89,56 +89,142 @@ const styleFunctionsOf = (objExpr) => {
89
89
  exports.styleFunctionsOf = styleFunctionsOf;
90
90
  const isUnitlessProp = (prop) => zss_engine_1.exceptionCamelCase.includes(prop) || prop.startsWith('--');
91
91
  exports.isUnitlessProp = isUnitlessProp;
92
- const collectVarProps = (style, cssVar, props) => {
93
- const reference = `var(${cssVar})`;
94
- for (const [prop, value] of Object.entries(style)) {
95
- if (typeof value === 'string' && value.includes(reference))
96
- props.push(prop);
97
- else if (value !== null && typeof value === 'object')
98
- collectVarProps(value, cssVar, props);
99
- }
92
+ const cssUnits = [
93
+ 'px',
94
+ 'cm',
95
+ 'mm',
96
+ 'q',
97
+ 'in',
98
+ 'pc',
99
+ 'pt',
100
+ 'cap',
101
+ 'ch',
102
+ 'em',
103
+ 'ex',
104
+ 'ic',
105
+ 'lh',
106
+ 'rcap',
107
+ 'rch',
108
+ 'rem',
109
+ 'rex',
110
+ 'ric',
111
+ 'rlh',
112
+ 'vh',
113
+ 'vw',
114
+ 'vmin',
115
+ 'vmax',
116
+ 'vb',
117
+ 'vi',
118
+ 'svw',
119
+ 'svh',
120
+ 'svmin',
121
+ 'svmax',
122
+ 'svb',
123
+ 'svi',
124
+ 'lvw',
125
+ 'lvh',
126
+ 'lvmin',
127
+ 'lvmax',
128
+ 'lvb',
129
+ 'lvi',
130
+ 'dvw',
131
+ 'dvh',
132
+ 'dvmin',
133
+ 'dvmax',
134
+ 'dvb',
135
+ 'dvi',
136
+ 'cqw',
137
+ 'cqh',
138
+ 'cqi',
139
+ 'cqb',
140
+ 'cqmin',
141
+ 'cqmax',
142
+ 'deg',
143
+ 'grad',
144
+ 'rad',
145
+ 'turn',
146
+ 's',
147
+ 'ms',
148
+ 'hz',
149
+ 'khz',
150
+ 'dpi',
151
+ 'dpcm',
152
+ 'dppx',
153
+ 'x',
154
+ 'fr',
155
+ ];
156
+ const UNIT_TOKEN = /^(%|[a-z]+[a-z0-9-]*)/i;
157
+ const unitSet = new Set(cssUnits);
158
+ const writtenUnitAfter = (rest) => {
159
+ const token = UNIT_TOKEN.exec(rest)?.[0];
160
+ if (token === undefined)
161
+ return '';
162
+ if (token === '%')
163
+ return token;
164
+ return unitSet.has(token.toLowerCase()) ? token : '';
165
+ };
166
+ const unitAt = (prop, rest) => {
167
+ const written = writtenUnitAfter(rest);
168
+ if (written)
169
+ return { unit: written, written: true };
170
+ return { unit: (0, exports.isUnitlessProp)(prop) ? '' : 'px', written: false };
100
171
  };
101
- const retargetVar = (style, cssVar, next, unitless) => {
172
+ const unitKey = (unit) => `${unit.written ? 'written' : 'default'}:${unit.unit}`;
173
+ const unitSlug = (unit) => unit.unit === '%' ? 'percent' : unit.unit || 'unitless';
174
+ const rewriteVarOccurrences = (style, cssVar, assign) => {
102
175
  const reference = `var(${cssVar})`;
103
176
  for (const [prop, value] of Object.entries(style)) {
104
177
  if (typeof value === 'string' && value.includes(reference)) {
105
- if ((0, exports.isUnitlessProp)(prop) === unitless)
106
- style[prop] = value
107
- .split(reference)
108
- .join(`var(${next})`);
178
+ let rewritten = '';
179
+ let rest = value;
180
+ let at = rest.indexOf(reference);
181
+ while (at !== -1) {
182
+ const after = rest.slice(at + reference.length);
183
+ const unit = unitAt(prop, after);
184
+ rewritten += `${rest.slice(0, at)}var(${assign(prop, unit)})`;
185
+ rest = unit.written ? after.slice(unit.unit.length) : after;
186
+ at = rest.indexOf(reference);
187
+ }
188
+ style[prop] = rewritten + rest;
109
189
  }
110
190
  else if (value !== null && typeof value === 'object') {
111
- retargetVar(value, cssVar, next, unitless);
191
+ rewriteVarOccurrences(value, cssVar, assign);
112
192
  }
113
193
  }
114
194
  };
115
195
  const splitVarByUnit = (style, cssVar) => {
116
- const props = [];
117
- collectVarProps(style, cssVar, props);
118
- if (props.length === 0)
119
- return [];
120
- const lead = props[0];
121
- const split = props.find((prop) => (0, exports.isUnitlessProp)(prop) !== (0, exports.isUnitlessProp)(lead));
122
- if (!split)
123
- return [{ cssVar, prop: lead }];
124
- const splitVar = `${cssVar}-${(0, zss_engine_1.camelToKebabCase)(split).replace(/^-+/, '')}`;
125
- retargetVar(style, cssVar, splitVar, (0, exports.isUnitlessProp)(split));
126
- return [
127
- { cssVar, prop: lead },
128
- { cssVar: splitVar, prop: split },
129
- ];
196
+ const groups = new Map();
197
+ const taken = new Set();
198
+ rewriteVarOccurrences(style, cssVar, (prop, unit) => {
199
+ const key = unitKey(unit);
200
+ const group = groups.get(key);
201
+ if (group)
202
+ return group.cssVar;
203
+ let name = cssVar;
204
+ if (groups.size > 0) {
205
+ const base = `${cssVar}-${(0, zss_engine_1.camelToKebabCase)(prop).replace(/^-+/, '')}`;
206
+ name = taken.has(base) ? `${base}-${unitSlug(unit)}` : base;
207
+ }
208
+ taken.add(name);
209
+ groups.set(key, { cssVar: name, prop, ...unit });
210
+ return name;
211
+ });
212
+ return Array.from(groups.values());
130
213
  };
131
214
  exports.splitVarByUnit = splitVarByUnit;
132
- const applyVarFallback = (style, cssVar, literal) => {
215
+ const applyVarFallback = (style, cssVar, literal, unit) => {
133
216
  const reference = `var(${cssVar})`;
134
217
  for (const [prop, value] of Object.entries(style)) {
135
218
  if (typeof value === 'string' && value.includes(reference)) {
219
+ const fallback = unit.written
220
+ ? `${literal}${unit.unit}`
221
+ : (0, zss_engine_1.applyCssValue)(literal, (0, zss_engine_1.camelToKebabCase)(prop));
136
222
  style[prop] = value
137
223
  .split(reference)
138
- .join(`var(${cssVar}, ${(0, zss_engine_1.applyCssValue)(literal, (0, zss_engine_1.camelToKebabCase)(prop))})`);
224
+ .join(`var(${cssVar}, ${fallback})`);
139
225
  }
140
226
  else if (value !== null && typeof value === 'object') {
141
- (0, exports.applyVarFallback)(value, cssVar, literal);
227
+ (0, exports.applyVarFallback)(value, cssVar, literal, unit);
142
228
  }
143
229
  }
144
230
  };
@@ -190,7 +276,7 @@ const resolveDynamicStyle = (func, runtimeParams, staticTable, tables, providedP
190
276
  return;
191
277
  varGroups
192
278
  .get(param)
193
- .forEach(({ cssVar }) => (0, exports.applyVarFallback)(style, cssVar, literal));
279
+ .forEach(({ cssVar, unit, written }) => (0, exports.applyVarFallback)(style, cssVar, literal, { unit, written }));
194
280
  });
195
281
  return { style, varGroups };
196
282
  };
package/dist/transform.js CHANGED
@@ -1107,20 +1107,33 @@ const transformSource = async (env) => {
1107
1107
  .subarray(argStart, argEnd)
1108
1108
  .toString('utf-8');
1109
1109
  const maybeNumber = Number(argSource);
1110
- groups.forEach(({ cssVar, prop }) => {
1110
+ groups.forEach(({ cssVar, prop, unit, written }) => {
1111
1111
  let valueExpr;
1112
1112
  const kebabProp = (0, zss_engine_1.camelToKebabCase)(prop);
1113
- if (!isNaN(maybeNumber) && argSource.trim() === String(maybeNumber)) {
1113
+ const isNumberLiteral = !isNaN(maybeNumber) && argSource.trim() === String(maybeNumber);
1114
+ const isStringLiteral = (argSource.startsWith('"') && argSource.endsWith('"')) ||
1115
+ (argSource.startsWith("'") && argSource.endsWith("'"));
1116
+ if (written) {
1117
+ if (isNumberLiteral) {
1118
+ valueExpr = JSON.stringify(`${maybeNumber}${unit}`);
1119
+ }
1120
+ else if (isStringLiteral) {
1121
+ valueExpr = JSON.stringify(`${argSource.slice(1, -1)}${unit}`);
1122
+ }
1123
+ else {
1124
+ valueExpr = `((${argSource}) + '${unit}')`;
1125
+ }
1126
+ }
1127
+ else if (isNumberLiteral) {
1114
1128
  valueExpr = JSON.stringify((0, zss_engine_1.applyCssValue)(maybeNumber, kebabProp));
1115
1129
  }
1116
- else if ((argSource.startsWith('"') && argSource.endsWith('"')) ||
1117
- (argSource.startsWith("'") && argSource.endsWith("'"))) {
1130
+ else if (isStringLiteral) {
1118
1131
  valueExpr = JSON.stringify((0, zss_engine_1.applyCssValue)(argSource.slice(1, -1), kebabProp));
1119
1132
  }
1120
1133
  else {
1121
- valueExpr = (0, dynamicKey_1.isUnitlessProp)(prop)
1122
- ? argSource
1123
- : `(typeof (${argSource}) === 'number' ? (${argSource}) + 'px' : (${argSource}))`;
1134
+ valueExpr = unit
1135
+ ? `(typeof (${argSource}) === 'number' ? (${argSource}) + '${unit}' : (${argSource}))`
1136
+ : argSource;
1124
1137
  }
1125
1138
  vars.push({ cssVar, valueExpr });
1126
1139
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plumeria/utils",
3
- "version": "19.2.1",
3
+ "version": "19.2.3",
4
4
  "description": "Plumeria Utils",
5
5
  "author": "Refirst 11",
6
6
  "license": "MIT",