@nordcraft/search 1.0.87 → 1.0.88
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.
- package/dist/rules/issues/style/invalidStyleSyntaxRule.js +16 -0
- package/dist/rules/issues/style/invalidStyleSyntaxRule.js.map +1 -1
- package/package.json +3 -3
- package/src/rules/issues/actions/unknownActionEventRule.test.ts +0 -1
- package/src/rules/issues/events/noReferenceEventRule.test.ts +0 -4
- package/src/rules/issues/events/unknownEventRule.test.ts +0 -4
- package/src/rules/issues/events/unknownTriggerEventRule.test.ts +0 -2
- package/src/rules/issues/style/invalidStyleSyntaxRule.test.ts +386 -0
- package/src/rules/issues/style/invalidStyleSyntaxRule.ts +21 -0
|
@@ -8,6 +8,22 @@ export const invalidStyleSyntaxRule = {
|
|
|
8
8
|
if (nodeType !== 'style-declaration') {
|
|
9
9
|
return;
|
|
10
10
|
}
|
|
11
|
+
// Check for variable/formula references: Variables., Formulas., Event., Attributes., Apis., Parameters., ListItem., URLParameters.
|
|
12
|
+
if (typeof value.styleValue === 'string') {
|
|
13
|
+
const hasVariableReference = /\b(Variables|Formulas|Event|Attributes|Apis|Parameters|ListItem|URLParameters)\.\w+/i.test(value.styleValue);
|
|
14
|
+
if (hasVariableReference) {
|
|
15
|
+
report({
|
|
16
|
+
path,
|
|
17
|
+
info: {
|
|
18
|
+
title: `Formulas detected in style declaration`,
|
|
19
|
+
description: `The style declaration for the property "${value.styleProperty}" contains Nordcraft formula syntax (e.g., references like "Variables.xxx", "Event.xxx", "Attributes.xxx", etc.). Formulas should not be used directly in CSS style values. Use style-variables or computed styles instead.`,
|
|
20
|
+
},
|
|
21
|
+
details: { property: value.styleProperty },
|
|
22
|
+
fixes: ['delete-style-property'],
|
|
23
|
+
});
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
11
27
|
const valid = memo(`valid-style-${value.styleProperty}:${value.styleValue}`, () => {
|
|
12
28
|
try {
|
|
13
29
|
parse(`${value.styleProperty}: ${value.styleValue}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invalidStyleSyntaxRule.js","sourceRoot":"","sources":["../../../../src/rules/issues/style/invalidStyleSyntaxRule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAE/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAElE,MAAM,CAAC,MAAM,sBAAsB,GAE9B;IACH,IAAI,EAAE,sBAAsB;IAC5B,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,SAAS;IACnB,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QAClD,IAAI,QAAQ,KAAK,mBAAmB,EAAE,CAAC;YACrC,OAAM;QACR,CAAC;
|
|
1
|
+
{"version":3,"file":"invalidStyleSyntaxRule.js","sourceRoot":"","sources":["../../../../src/rules/issues/style/invalidStyleSyntaxRule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAE/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAElE,MAAM,CAAC,MAAM,sBAAsB,GAE9B;IACH,IAAI,EAAE,sBAAsB;IAC5B,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,SAAS;IACnB,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QAClD,IAAI,QAAQ,KAAK,mBAAmB,EAAE,CAAC;YACrC,OAAM;QACR,CAAC;QAED,mIAAmI;QACnI,IAAI,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;YACzC,MAAM,oBAAoB,GACxB,sFAAsF,CAAC,IAAI,CACzF,KAAK,CAAC,UAAU,CACjB,CAAA;YACH,IAAI,oBAAoB,EAAE,CAAC;gBACzB,MAAM,CAAC;oBACL,IAAI;oBACJ,IAAI,EAAE;wBACJ,KAAK,EAAE,wCAAwC;wBAC/C,WAAW,EAAE,2CAA2C,KAAK,CAAC,aAAa,6NAA6N;qBACzS;oBACD,OAAO,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,aAAa,EAAE;oBAC1C,KAAK,EAAE,CAAC,uBAAuB,CAAC;iBACjC,CAAC,CAAA;gBACF,OAAM;YACR,CAAC;QACH,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAChB,eAAe,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,UAAU,EAAE,EACxD,GAAG,EAAE,CAAC;YACJ,IAAI,CAAC;gBACH,KAAK,CAAC,GAAG,KAAK,CAAC,aAAa,KAAK,KAAK,CAAC,UAAU,EAAE,CAAC,CAAA;gBACpD,OAAO,IAAI,CAAA;YACb,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAA;YACd,CAAC;QAAA,CACF,CACF,CAAA;QACD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,CAAC;gBACL,IAAI;gBACJ,IAAI,EAAE;oBACJ,KAAK,EAAE,2BAA2B;oBAClC,WAAW,EAAE,2CAA2C,KAAK,CAAC,aAAa,kIAAkI;iBAC9M;gBACD,OAAO,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,aAAa,EAAE;gBAC1C,KAAK,EAAE,CAAC,uBAAuB,CAAC;aACjC,CAAC,CAAA;QACJ,CAAC;IAAA,CACF;IACD,KAAK,EAAE;QACL,uBAAuB,EAAE,iBAAiB;KAC3C;CACF,CAAA"}
|
package/package.json
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"directory": "packages/search"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@nordcraft/ssr": "1.0.
|
|
14
|
-
"@nordcraft/core": "1.0.
|
|
13
|
+
"@nordcraft/ssr": "1.0.88",
|
|
14
|
+
"@nordcraft/core": "1.0.88",
|
|
15
15
|
"jsondiffpatch": "0.7.3",
|
|
16
16
|
"postcss": "8.5.6",
|
|
17
17
|
"zod": "4.2.1"
|
|
@@ -26,5 +26,5 @@
|
|
|
26
26
|
"test:watch:only": "bun test --watch --only"
|
|
27
27
|
},
|
|
28
28
|
"files": ["dist", "src"],
|
|
29
|
-
"version": "1.0.
|
|
29
|
+
"version": "1.0.88"
|
|
30
30
|
}
|
|
@@ -42,7 +42,6 @@ describe('find noReferenceEventRule', () => {
|
|
|
42
42
|
events: [
|
|
43
43
|
{
|
|
44
44
|
name: 'unused-event',
|
|
45
|
-
// eslint-disable-next-line inclusive-language/use-inclusive-words
|
|
46
45
|
dummyEvent: {
|
|
47
46
|
name: 'Name',
|
|
48
47
|
},
|
|
@@ -120,7 +119,6 @@ describe('find noReferenceEventRule', () => {
|
|
|
120
119
|
events: [
|
|
121
120
|
{
|
|
122
121
|
name: 'known-event',
|
|
123
|
-
// eslint-disable-next-line inclusive-language/use-inclusive-words
|
|
124
122
|
dummyEvent: {
|
|
125
123
|
name: 'Name',
|
|
126
124
|
},
|
|
@@ -130,7 +128,6 @@ describe('find noReferenceEventRule', () => {
|
|
|
130
128
|
},
|
|
131
129
|
{
|
|
132
130
|
name: 'used-event',
|
|
133
|
-
// eslint-disable-next-line inclusive-language/use-inclusive-words
|
|
134
131
|
dummyEvent: {
|
|
135
132
|
name: 'Name',
|
|
136
133
|
},
|
|
@@ -184,7 +181,6 @@ describe('fix noReferenceEventRule', () => {
|
|
|
184
181
|
events: [
|
|
185
182
|
{
|
|
186
183
|
name: 'unused-event',
|
|
187
|
-
// eslint-disable-next-line inclusive-language/use-inclusive-words
|
|
188
184
|
dummyEvent: {
|
|
189
185
|
name: 'Name',
|
|
190
186
|
},
|
|
@@ -66,7 +66,6 @@ describe('unknownEvent', () => {
|
|
|
66
66
|
events: [
|
|
67
67
|
{
|
|
68
68
|
name: 'known-event',
|
|
69
|
-
// eslint-disable-next-line inclusive-language/use-inclusive-words
|
|
70
69
|
dummyEvent: {
|
|
71
70
|
name: 'Name',
|
|
72
71
|
},
|
|
@@ -94,7 +93,6 @@ describe('unknownEvent', () => {
|
|
|
94
93
|
events: [
|
|
95
94
|
{
|
|
96
95
|
name: 'known-event',
|
|
97
|
-
// eslint-disable-next-line inclusive-language/use-inclusive-words
|
|
98
96
|
dummyEvent: {
|
|
99
97
|
name: 'Name',
|
|
100
98
|
},
|
|
@@ -187,7 +185,6 @@ describe('unknownEvent', () => {
|
|
|
187
185
|
events: [
|
|
188
186
|
{
|
|
189
187
|
name: 'known-event',
|
|
190
|
-
// eslint-disable-next-line inclusive-language/use-inclusive-words
|
|
191
188
|
dummyEvent: {
|
|
192
189
|
name: 'Name',
|
|
193
190
|
},
|
|
@@ -215,7 +212,6 @@ describe('unknownEvent', () => {
|
|
|
215
212
|
events: [
|
|
216
213
|
{
|
|
217
214
|
name: 'known-event',
|
|
218
|
-
// eslint-disable-next-line inclusive-language/use-inclusive-words
|
|
219
215
|
dummyEvent: {
|
|
220
216
|
name: 'Name',
|
|
221
217
|
},
|
|
@@ -40,7 +40,6 @@ describe('unknownTriggerEventRule', () => {
|
|
|
40
40
|
events: [
|
|
41
41
|
{
|
|
42
42
|
name: 'known-event',
|
|
43
|
-
// eslint-disable-next-line inclusive-language/use-inclusive-words
|
|
44
43
|
dummyEvent: {
|
|
45
44
|
name: 'Name',
|
|
46
45
|
},
|
|
@@ -97,7 +96,6 @@ describe('unknownTriggerEventRule', () => {
|
|
|
97
96
|
events: [
|
|
98
97
|
{
|
|
99
98
|
name: 'known-event',
|
|
100
|
-
// eslint-disable-next-line inclusive-language/use-inclusive-words
|
|
101
99
|
dummyEvent: {
|
|
102
100
|
name: 'Name',
|
|
103
101
|
},
|
|
@@ -203,6 +203,298 @@ describe('find invalidStyleSyntaxRule', () => {
|
|
|
203
203
|
})
|
|
204
204
|
})
|
|
205
205
|
|
|
206
|
+
describe('find formulas in style syntax', () => {
|
|
207
|
+
test('should find Variables. references in style syntax', () => {
|
|
208
|
+
const problems = Array.from(
|
|
209
|
+
searchProject({
|
|
210
|
+
files: {
|
|
211
|
+
formulas: {},
|
|
212
|
+
components: {
|
|
213
|
+
test: {
|
|
214
|
+
name: 'test',
|
|
215
|
+
nodes: {
|
|
216
|
+
root: {
|
|
217
|
+
tag: 'div',
|
|
218
|
+
type: 'element',
|
|
219
|
+
attrs: {},
|
|
220
|
+
style: {
|
|
221
|
+
transform: 'translateX(Variables.offsetX)',
|
|
222
|
+
width: '100px',
|
|
223
|
+
height: 'Variables.height',
|
|
224
|
+
},
|
|
225
|
+
events: {},
|
|
226
|
+
classes: {},
|
|
227
|
+
children: [],
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
formulas: {},
|
|
231
|
+
apis: {},
|
|
232
|
+
attributes: {},
|
|
233
|
+
variables: {},
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
rules: [invalidStyleSyntaxRule],
|
|
238
|
+
}),
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
expect(problems).toMatchObject([
|
|
242
|
+
{
|
|
243
|
+
code: 'invalid style syntax',
|
|
244
|
+
path: ['components', 'test', 'nodes', 'root', 'style', 'transform'],
|
|
245
|
+
details: { property: 'transform' },
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
code: 'invalid style syntax',
|
|
249
|
+
path: ['components', 'test', 'nodes', 'root', 'style', 'height'],
|
|
250
|
+
details: { property: 'height' },
|
|
251
|
+
},
|
|
252
|
+
])
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
test('should find Formulas., Event., Attributes., Apis., Parameters., ListItem., URLParameters. references', () => {
|
|
256
|
+
const problems = Array.from(
|
|
257
|
+
searchProject({
|
|
258
|
+
files: {
|
|
259
|
+
formulas: {},
|
|
260
|
+
components: {
|
|
261
|
+
test: {
|
|
262
|
+
name: 'test',
|
|
263
|
+
nodes: {
|
|
264
|
+
root: {
|
|
265
|
+
tag: 'div',
|
|
266
|
+
type: 'element',
|
|
267
|
+
attrs: {},
|
|
268
|
+
style: {
|
|
269
|
+
color: 'Formulas.getColor()',
|
|
270
|
+
top: 'Event.clientY',
|
|
271
|
+
margin: 'Attributes.margin',
|
|
272
|
+
background: 'Apis.getBackground()',
|
|
273
|
+
fontSize: 'Parameters.size',
|
|
274
|
+
backgroundColor: 'ListItem.color',
|
|
275
|
+
width: 'URLParameters.width',
|
|
276
|
+
},
|
|
277
|
+
events: {},
|
|
278
|
+
classes: {},
|
|
279
|
+
children: [],
|
|
280
|
+
},
|
|
281
|
+
},
|
|
282
|
+
formulas: {},
|
|
283
|
+
apis: {},
|
|
284
|
+
attributes: {},
|
|
285
|
+
variables: {},
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
},
|
|
289
|
+
rules: [invalidStyleSyntaxRule],
|
|
290
|
+
}),
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
expect(problems).toHaveLength(7)
|
|
294
|
+
expect(problems.map((p) => p.details.property)).toEqual([
|
|
295
|
+
'color',
|
|
296
|
+
'top',
|
|
297
|
+
'margin',
|
|
298
|
+
'background',
|
|
299
|
+
'fontSize',
|
|
300
|
+
'backgroundColor',
|
|
301
|
+
'width',
|
|
302
|
+
])
|
|
303
|
+
})
|
|
304
|
+
|
|
305
|
+
test('should not find formulas in valid CSS values', () => {
|
|
306
|
+
const problems = Array.from(
|
|
307
|
+
searchProject({
|
|
308
|
+
files: {
|
|
309
|
+
formulas: {},
|
|
310
|
+
components: {
|
|
311
|
+
test: {
|
|
312
|
+
name: 'test',
|
|
313
|
+
nodes: {
|
|
314
|
+
root: {
|
|
315
|
+
tag: 'div',
|
|
316
|
+
type: 'element',
|
|
317
|
+
attrs: {},
|
|
318
|
+
style: {
|
|
319
|
+
width: '100px',
|
|
320
|
+
height: '50%',
|
|
321
|
+
color: '#ffffff',
|
|
322
|
+
backgroundColor: 'var(--my-var)',
|
|
323
|
+
transform: 'translateX(10px)',
|
|
324
|
+
margin: '10px 20px',
|
|
325
|
+
},
|
|
326
|
+
events: {},
|
|
327
|
+
classes: {},
|
|
328
|
+
children: [],
|
|
329
|
+
},
|
|
330
|
+
},
|
|
331
|
+
formulas: {},
|
|
332
|
+
apis: {},
|
|
333
|
+
attributes: {},
|
|
334
|
+
variables: {},
|
|
335
|
+
},
|
|
336
|
+
},
|
|
337
|
+
},
|
|
338
|
+
rules: [invalidStyleSyntaxRule],
|
|
339
|
+
}),
|
|
340
|
+
)
|
|
341
|
+
|
|
342
|
+
expect(problems).toHaveLength(0)
|
|
343
|
+
})
|
|
344
|
+
|
|
345
|
+
test('should not find formulas in numeric style values', () => {
|
|
346
|
+
const problems = Array.from(
|
|
347
|
+
searchProject({
|
|
348
|
+
files: {
|
|
349
|
+
formulas: {},
|
|
350
|
+
components: {
|
|
351
|
+
test: {
|
|
352
|
+
name: 'test',
|
|
353
|
+
nodes: {
|
|
354
|
+
root: {
|
|
355
|
+
tag: 'div',
|
|
356
|
+
type: 'element',
|
|
357
|
+
attrs: {},
|
|
358
|
+
style: {
|
|
359
|
+
opacity: 0.5,
|
|
360
|
+
zIndex: 10,
|
|
361
|
+
flex: 1,
|
|
362
|
+
},
|
|
363
|
+
events: {},
|
|
364
|
+
classes: {},
|
|
365
|
+
children: [],
|
|
366
|
+
},
|
|
367
|
+
},
|
|
368
|
+
formulas: {},
|
|
369
|
+
apis: {},
|
|
370
|
+
attributes: {},
|
|
371
|
+
variables: {},
|
|
372
|
+
},
|
|
373
|
+
},
|
|
374
|
+
},
|
|
375
|
+
rules: [invalidStyleSyntaxRule],
|
|
376
|
+
}),
|
|
377
|
+
)
|
|
378
|
+
|
|
379
|
+
expect(problems).toHaveLength(0)
|
|
380
|
+
})
|
|
381
|
+
|
|
382
|
+
test('should find formulas in variant styles', () => {
|
|
383
|
+
const problems = Array.from(
|
|
384
|
+
searchProject({
|
|
385
|
+
files: {
|
|
386
|
+
formulas: {},
|
|
387
|
+
components: {
|
|
388
|
+
test: {
|
|
389
|
+
name: 'test',
|
|
390
|
+
nodes: {
|
|
391
|
+
root: {
|
|
392
|
+
tag: 'div',
|
|
393
|
+
type: 'element',
|
|
394
|
+
attrs: {},
|
|
395
|
+
style: {
|
|
396
|
+
width: '100px',
|
|
397
|
+
},
|
|
398
|
+
events: {},
|
|
399
|
+
classes: {},
|
|
400
|
+
children: [],
|
|
401
|
+
variants: [
|
|
402
|
+
{
|
|
403
|
+
style: {
|
|
404
|
+
transform: 'translateX(Variables.offsetX)',
|
|
405
|
+
color: 'Event.color',
|
|
406
|
+
},
|
|
407
|
+
hover: true,
|
|
408
|
+
},
|
|
409
|
+
],
|
|
410
|
+
},
|
|
411
|
+
},
|
|
412
|
+
formulas: {},
|
|
413
|
+
apis: {},
|
|
414
|
+
attributes: {},
|
|
415
|
+
variables: {},
|
|
416
|
+
},
|
|
417
|
+
},
|
|
418
|
+
},
|
|
419
|
+
rules: [invalidStyleSyntaxRule],
|
|
420
|
+
}),
|
|
421
|
+
)
|
|
422
|
+
|
|
423
|
+
expect(problems).toMatchObject([
|
|
424
|
+
{
|
|
425
|
+
code: 'invalid style syntax',
|
|
426
|
+
path: [
|
|
427
|
+
'components',
|
|
428
|
+
'test',
|
|
429
|
+
'nodes',
|
|
430
|
+
'root',
|
|
431
|
+
'variants',
|
|
432
|
+
0,
|
|
433
|
+
'style',
|
|
434
|
+
'transform',
|
|
435
|
+
],
|
|
436
|
+
details: { property: 'transform' },
|
|
437
|
+
},
|
|
438
|
+
{
|
|
439
|
+
code: 'invalid style syntax',
|
|
440
|
+
path: [
|
|
441
|
+
'components',
|
|
442
|
+
'test',
|
|
443
|
+
'nodes',
|
|
444
|
+
'root',
|
|
445
|
+
'variants',
|
|
446
|
+
0,
|
|
447
|
+
'style',
|
|
448
|
+
'color',
|
|
449
|
+
],
|
|
450
|
+
details: { property: 'color' },
|
|
451
|
+
},
|
|
452
|
+
])
|
|
453
|
+
})
|
|
454
|
+
|
|
455
|
+
test('should handle case-insensitive matching for formulas', () => {
|
|
456
|
+
const problems = Array.from(
|
|
457
|
+
searchProject({
|
|
458
|
+
files: {
|
|
459
|
+
formulas: {},
|
|
460
|
+
components: {
|
|
461
|
+
test: {
|
|
462
|
+
name: 'test',
|
|
463
|
+
nodes: {
|
|
464
|
+
root: {
|
|
465
|
+
tag: 'div',
|
|
466
|
+
type: 'element',
|
|
467
|
+
attrs: {},
|
|
468
|
+
style: {
|
|
469
|
+
width: 'VARIABLES.offsetX',
|
|
470
|
+
height: 'variables.height',
|
|
471
|
+
color: 'FORMULAS.getColor()',
|
|
472
|
+
},
|
|
473
|
+
events: {},
|
|
474
|
+
classes: {},
|
|
475
|
+
children: [],
|
|
476
|
+
},
|
|
477
|
+
},
|
|
478
|
+
formulas: {},
|
|
479
|
+
apis: {},
|
|
480
|
+
attributes: {},
|
|
481
|
+
variables: {},
|
|
482
|
+
},
|
|
483
|
+
},
|
|
484
|
+
},
|
|
485
|
+
rules: [invalidStyleSyntaxRule],
|
|
486
|
+
}),
|
|
487
|
+
)
|
|
488
|
+
|
|
489
|
+
expect(problems).toHaveLength(3)
|
|
490
|
+
expect(problems.map((p) => p.details.property)).toEqual([
|
|
491
|
+
'width',
|
|
492
|
+
'height',
|
|
493
|
+
'color',
|
|
494
|
+
])
|
|
495
|
+
})
|
|
496
|
+
})
|
|
497
|
+
|
|
206
498
|
describe('fix invalidStyleSyntaxRule', () => {
|
|
207
499
|
test('should remove an invalid style property', () => {
|
|
208
500
|
const files: ProjectFiles = {
|
|
@@ -248,6 +540,49 @@ describe('fix invalidStyleSyntaxRule', () => {
|
|
|
248
540
|
}
|
|
249
541
|
`)
|
|
250
542
|
})
|
|
543
|
+
test('should remove a style property with formula syntax', () => {
|
|
544
|
+
const files: ProjectFiles = {
|
|
545
|
+
formulas: {},
|
|
546
|
+
components: {
|
|
547
|
+
test: {
|
|
548
|
+
name: 'test',
|
|
549
|
+
nodes: {
|
|
550
|
+
root: {
|
|
551
|
+
tag: 'div',
|
|
552
|
+
type: 'element',
|
|
553
|
+
attrs: {},
|
|
554
|
+
style: {
|
|
555
|
+
width: '100px',
|
|
556
|
+
transform: 'translateX(Variables.offsetX)',
|
|
557
|
+
height: '50px',
|
|
558
|
+
color: 'Variables.color',
|
|
559
|
+
},
|
|
560
|
+
events: {},
|
|
561
|
+
classes: {},
|
|
562
|
+
children: [],
|
|
563
|
+
},
|
|
564
|
+
},
|
|
565
|
+
formulas: {},
|
|
566
|
+
apis: {},
|
|
567
|
+
attributes: {},
|
|
568
|
+
variables: {},
|
|
569
|
+
},
|
|
570
|
+
},
|
|
571
|
+
}
|
|
572
|
+
const fixedFiles = fixProject({
|
|
573
|
+
files,
|
|
574
|
+
rule: invalidStyleSyntaxRule,
|
|
575
|
+
fixType: 'delete-style-property',
|
|
576
|
+
})
|
|
577
|
+
expect((fixedFiles.components.test!.nodes?.root as ElementNodeModel).style)
|
|
578
|
+
.toMatchInlineSnapshot(`
|
|
579
|
+
{
|
|
580
|
+
"height": "50px",
|
|
581
|
+
"width": "100px",
|
|
582
|
+
}
|
|
583
|
+
`)
|
|
584
|
+
})
|
|
585
|
+
|
|
251
586
|
test('should remove an invalid style variant style property', () => {
|
|
252
587
|
const files: ProjectFiles = {
|
|
253
588
|
formulas: {},
|
|
@@ -300,4 +635,55 @@ describe('fix invalidStyleSyntaxRule', () => {
|
|
|
300
635
|
}
|
|
301
636
|
`)
|
|
302
637
|
})
|
|
638
|
+
|
|
639
|
+
test('should remove a variant style property with formula syntax', () => {
|
|
640
|
+
const files: ProjectFiles = {
|
|
641
|
+
formulas: {},
|
|
642
|
+
components: {
|
|
643
|
+
test: {
|
|
644
|
+
name: 'test',
|
|
645
|
+
nodes: {
|
|
646
|
+
root: {
|
|
647
|
+
tag: 'div',
|
|
648
|
+
type: 'element',
|
|
649
|
+
attrs: {},
|
|
650
|
+
style: {},
|
|
651
|
+
events: {},
|
|
652
|
+
classes: {},
|
|
653
|
+
children: [],
|
|
654
|
+
variants: [
|
|
655
|
+
{
|
|
656
|
+
style: {
|
|
657
|
+
width: '100px',
|
|
658
|
+
transform: 'translateX(Variables.offsetX)',
|
|
659
|
+
height: '50px',
|
|
660
|
+
color: 'Event.color',
|
|
661
|
+
},
|
|
662
|
+
hover: true,
|
|
663
|
+
},
|
|
664
|
+
],
|
|
665
|
+
},
|
|
666
|
+
},
|
|
667
|
+
formulas: {},
|
|
668
|
+
apis: {},
|
|
669
|
+
attributes: {},
|
|
670
|
+
variables: {},
|
|
671
|
+
},
|
|
672
|
+
},
|
|
673
|
+
}
|
|
674
|
+
const fixedFiles = fixProject({
|
|
675
|
+
files,
|
|
676
|
+
rule: invalidStyleSyntaxRule,
|
|
677
|
+
fixType: 'delete-style-property',
|
|
678
|
+
})
|
|
679
|
+
expect(
|
|
680
|
+
(fixedFiles.components.test!.nodes?.root as ElementNodeModel)
|
|
681
|
+
.variants?.[0].style,
|
|
682
|
+
).toMatchInlineSnapshot(`
|
|
683
|
+
{
|
|
684
|
+
"height": "50px",
|
|
685
|
+
"width": "100px",
|
|
686
|
+
}
|
|
687
|
+
`)
|
|
688
|
+
})
|
|
303
689
|
})
|
|
@@ -12,6 +12,27 @@ export const invalidStyleSyntaxRule: Rule<{
|
|
|
12
12
|
if (nodeType !== 'style-declaration') {
|
|
13
13
|
return
|
|
14
14
|
}
|
|
15
|
+
|
|
16
|
+
// Check for variable/formula references: Variables., Formulas., Event., Attributes., Apis., Parameters., ListItem., URLParameters.
|
|
17
|
+
if (typeof value.styleValue === 'string') {
|
|
18
|
+
const hasVariableReference =
|
|
19
|
+
/\b(Variables|Formulas|Event|Attributes|Apis|Parameters|ListItem|URLParameters)\.\w+/i.test(
|
|
20
|
+
value.styleValue,
|
|
21
|
+
)
|
|
22
|
+
if (hasVariableReference) {
|
|
23
|
+
report({
|
|
24
|
+
path,
|
|
25
|
+
info: {
|
|
26
|
+
title: `Formulas detected in style declaration`,
|
|
27
|
+
description: `The style declaration for the property "${value.styleProperty}" contains Nordcraft formula syntax (e.g., references like "Variables.xxx", "Event.xxx", "Attributes.xxx", etc.). Formulas should not be used directly in CSS style values. Use style-variables or computed styles instead.`,
|
|
28
|
+
},
|
|
29
|
+
details: { property: value.styleProperty },
|
|
30
|
+
fixes: ['delete-style-property'],
|
|
31
|
+
})
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
15
36
|
const valid = memo(
|
|
16
37
|
`valid-style-${value.styleProperty}:${value.styleValue}`,
|
|
17
38
|
() => {
|