@plumeria/utils 19.2.1 → 19.2.2

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,136 @@ 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
+ 'lvw',
123
+ 'lvh',
124
+ 'lvmin',
125
+ 'lvmax',
126
+ 'dvw',
127
+ 'dvh',
128
+ 'dvmin',
129
+ 'dvmax',
130
+ 'cqw',
131
+ 'cqh',
132
+ 'cqi',
133
+ 'cqb',
134
+ 'cqmin',
135
+ 'cqmax',
136
+ 'deg',
137
+ 'grad',
138
+ 'rad',
139
+ 'turn',
140
+ 's',
141
+ 'ms',
142
+ 'hz',
143
+ 'khz',
144
+ 'dpi',
145
+ 'dpcm',
146
+ 'dppx',
147
+ 'x',
148
+ 'fr',
149
+ ];
150
+ const UNIT_TOKEN = /^(%|[a-z]+[a-z0-9-]*)/i;
151
+ const unitSet = new Set(cssUnits);
152
+ const writtenUnitAfter = (rest) => {
153
+ const token = UNIT_TOKEN.exec(rest)?.[0];
154
+ if (token === undefined)
155
+ return '';
156
+ if (token === '%')
157
+ return token;
158
+ return unitSet.has(token.toLowerCase()) ? token : '';
159
+ };
160
+ const unitAt = (prop, rest) => {
161
+ const written = writtenUnitAfter(rest);
162
+ if (written)
163
+ return { unit: written, written: true };
164
+ return { unit: (0, exports.isUnitlessProp)(prop) ? '' : 'px', written: false };
100
165
  };
101
- const retargetVar = (style, cssVar, next, unitless) => {
166
+ const unitKey = (unit) => `${unit.written ? 'written' : 'default'}:${unit.unit}`;
167
+ const unitSlug = (unit) => unit.unit === '%' ? 'percent' : unit.unit || 'unitless';
168
+ const rewriteVarOccurrences = (style, cssVar, assign) => {
102
169
  const reference = `var(${cssVar})`;
103
170
  for (const [prop, value] of Object.entries(style)) {
104
171
  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})`);
172
+ let rewritten = '';
173
+ let rest = value;
174
+ let at = rest.indexOf(reference);
175
+ while (at !== -1) {
176
+ const after = rest.slice(at + reference.length);
177
+ const unit = unitAt(prop, after);
178
+ rewritten += `${rest.slice(0, at)}var(${assign(prop, unit)})`;
179
+ rest = unit.written ? after.slice(unit.unit.length) : after;
180
+ at = rest.indexOf(reference);
181
+ }
182
+ style[prop] = rewritten + rest;
109
183
  }
110
184
  else if (value !== null && typeof value === 'object') {
111
- retargetVar(value, cssVar, next, unitless);
185
+ rewriteVarOccurrences(value, cssVar, assign);
112
186
  }
113
187
  }
114
188
  };
115
189
  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
- ];
190
+ const groups = new Map();
191
+ const taken = new Set();
192
+ rewriteVarOccurrences(style, cssVar, (prop, unit) => {
193
+ const key = unitKey(unit);
194
+ const group = groups.get(key);
195
+ if (group)
196
+ return group.cssVar;
197
+ let name = cssVar;
198
+ if (groups.size > 0) {
199
+ const base = `${cssVar}-${(0, zss_engine_1.camelToKebabCase)(prop).replace(/^-+/, '')}`;
200
+ name = taken.has(base) ? `${base}-${unitSlug(unit)}` : base;
201
+ }
202
+ taken.add(name);
203
+ groups.set(key, { cssVar: name, prop, ...unit });
204
+ return name;
205
+ });
206
+ return Array.from(groups.values());
130
207
  };
131
208
  exports.splitVarByUnit = splitVarByUnit;
132
- const applyVarFallback = (style, cssVar, literal) => {
209
+ const applyVarFallback = (style, cssVar, literal, unit) => {
133
210
  const reference = `var(${cssVar})`;
134
211
  for (const [prop, value] of Object.entries(style)) {
135
212
  if (typeof value === 'string' && value.includes(reference)) {
213
+ const fallback = unit.written
214
+ ? `${literal}${unit.unit}`
215
+ : (0, zss_engine_1.applyCssValue)(literal, (0, zss_engine_1.camelToKebabCase)(prop));
136
216
  style[prop] = value
137
217
  .split(reference)
138
- .join(`var(${cssVar}, ${(0, zss_engine_1.applyCssValue)(literal, (0, zss_engine_1.camelToKebabCase)(prop))})`);
218
+ .join(`var(${cssVar}, ${fallback})`);
139
219
  }
140
220
  else if (value !== null && typeof value === 'object') {
141
- (0, exports.applyVarFallback)(value, cssVar, literal);
221
+ (0, exports.applyVarFallback)(value, cssVar, literal, unit);
142
222
  }
143
223
  }
144
224
  };
@@ -190,7 +270,7 @@ const resolveDynamicStyle = (func, runtimeParams, staticTable, tables, providedP
190
270
  return;
191
271
  varGroups
192
272
  .get(param)
193
- .forEach(({ cssVar }) => (0, exports.applyVarFallback)(style, cssVar, literal));
273
+ .forEach(({ cssVar, unit, written }) => (0, exports.applyVarFallback)(style, cssVar, literal, { unit, written }));
194
274
  });
195
275
  return { style, varGroups };
196
276
  };
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.2",
4
4
  "description": "Plumeria Utils",
5
5
  "author": "Refirst 11",
6
6
  "license": "MIT",