@wix/zero-config-implementation 1.45.0 → 1.46.0
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/index.js +12784 -12723
- package/package.json +2 -2
- package/src/converters/to-editor-component.ts +35 -3
- package/src/information-extractors/react/extractors/css-properties.test.ts +44 -0
- package/src/information-extractors/react/extractors/css-properties.ts +69 -6
- package/src/information-extractors/react/extractors/index.ts +6 -1
- package/src/information-extractors/react/index.ts +2 -0
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"registry": "https://registry.npmjs.org/",
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
|
-
"version": "1.
|
|
7
|
+
"version": "1.46.0",
|
|
8
8
|
"description": "Core library for extracting component manifests from JS and CSS files",
|
|
9
9
|
"type": "module",
|
|
10
10
|
"main": "dist/index.js",
|
|
@@ -84,5 +84,5 @@
|
|
|
84
84
|
]
|
|
85
85
|
}
|
|
86
86
|
},
|
|
87
|
-
"falconPackageHash": "
|
|
87
|
+
"falconPackageHash": "9f4aa3db6c672e0f49191ce43b8bf9de7c884e07c4765eef9a0ed3e7"
|
|
88
88
|
}
|
|
@@ -2,11 +2,12 @@ import type {
|
|
|
2
2
|
CssCustomPropertyItem,
|
|
3
3
|
CssPropertyItem,
|
|
4
4
|
DataItem,
|
|
5
|
+
Display,
|
|
5
6
|
EditorElement,
|
|
6
7
|
EditorReactComponent,
|
|
7
8
|
ElementItem,
|
|
8
9
|
} from '@wix/react-component-schema'
|
|
9
|
-
import { ELEMENTS } from '@wix/react-component-schema'
|
|
10
|
+
import { CSS_PROPERTIES, ELEMENTS } from '@wix/react-component-schema'
|
|
10
11
|
import type { ComponentInfoWithCss } from '../index'
|
|
11
12
|
import type { MatchedCssData } from '../information-extractors/css/types'
|
|
12
13
|
import type {
|
|
@@ -16,6 +17,7 @@ import type {
|
|
|
16
17
|
ExtractedElement,
|
|
17
18
|
TrackingStores,
|
|
18
19
|
} from '../information-extractors/react'
|
|
20
|
+
import { getDefaultDisplayForTag, resolveDisplayValue } from '../information-extractors/react'
|
|
19
21
|
import { findPreferredSemanticClass } from '../utils/css-class'
|
|
20
22
|
import { buildDataItem } from './data-item-builder'
|
|
21
23
|
import { formatDisplayName } from './utils'
|
|
@@ -308,10 +310,24 @@ function getMatchedPropertyValues(element: ExtractedElement): Map<string, string
|
|
|
308
310
|
return values
|
|
309
311
|
}
|
|
310
312
|
|
|
313
|
+
const CSS_DISPLAY_TO_ENUM: Record<string, string> = {
|
|
314
|
+
'inline-block': 'inlineBlock',
|
|
315
|
+
'inline-flex': 'inlineFlex',
|
|
316
|
+
'inline-grid': 'inlineGrid',
|
|
317
|
+
'inline-table': 'inlineTable',
|
|
318
|
+
'list-item': 'listItem',
|
|
319
|
+
'flow-root': 'flowRoot',
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
function toDisplayEnumValue(cssValue: string): NonNullable<Display['displayValues']>[number] {
|
|
323
|
+
return (CSS_DISPLAY_TO_ENUM[cssValue] ?? cssValue) as NonNullable<Display['displayValues']>[number]
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
const { CSS_PROPERTY_TYPE, DISPLAY_VALUE } = CSS_PROPERTIES
|
|
327
|
+
|
|
311
328
|
function buildCssProperties(element: ExtractedElement | undefined): Record<string, CssPropertyItem> {
|
|
312
329
|
const result: Record<string, CssPropertyItem> = {}
|
|
313
330
|
|
|
314
|
-
// Get the CSS properties decided by the heuristic
|
|
315
331
|
const cssData = element?.extractorData.get('css-properties') as CssPropertiesData | undefined
|
|
316
332
|
const decidedProperties = cssData?.relevant
|
|
317
333
|
if (!decidedProperties || decidedProperties.length === 0) {
|
|
@@ -319,12 +335,28 @@ function buildCssProperties(element: ExtractedElement | undefined): Record<strin
|
|
|
319
335
|
}
|
|
320
336
|
const cssPropertyValues = element ? getMatchedPropertyValues(element) : new Map<string, string>()
|
|
321
337
|
for (const propName of decidedProperties) {
|
|
338
|
+
if (propName === CSS_PROPERTY_TYPE.display && element) {
|
|
339
|
+
result[propName] = buildDisplayProperty(element)
|
|
340
|
+
continue
|
|
341
|
+
}
|
|
322
342
|
const defaultValue = cssPropertyValues.get(propName)
|
|
323
343
|
result[propName] = {
|
|
324
|
-
// Only include defaultValue if found in CSS files
|
|
325
344
|
...(defaultValue !== undefined && { defaultValue }),
|
|
326
345
|
}
|
|
327
346
|
}
|
|
328
347
|
|
|
329
348
|
return result
|
|
330
349
|
}
|
|
350
|
+
|
|
351
|
+
function buildDisplayProperty(element: ExtractedElement): CssPropertyItem {
|
|
352
|
+
const matcherData = element.extractorData.get('css-matcher') as MatchedCssData | undefined
|
|
353
|
+
const resolvedFromCss = matcherData ? resolveDisplayValue(matcherData) : undefined
|
|
354
|
+
const currentValue = resolvedFromCss ?? getDefaultDisplayForTag(element.tag)
|
|
355
|
+
const currentEnumValue = toDisplayEnumValue(currentValue)
|
|
356
|
+
|
|
357
|
+
return {
|
|
358
|
+
display: {
|
|
359
|
+
displayValues: [DISPLAY_VALUE.none, currentEnumValue],
|
|
360
|
+
},
|
|
361
|
+
}
|
|
362
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { parseCss } from '../../css/parse'
|
|
3
|
+
import type { MatchedCssData } from '../../css/types'
|
|
4
|
+
import { hasFlexOrGridDisplay } from './css-properties'
|
|
5
|
+
|
|
6
|
+
function matcherDataFromCss(declarations: string): MatchedCssData {
|
|
7
|
+
const properties = parseCss(`.test { ${declarations} }`).getPropertiesForSelector('.test')
|
|
8
|
+
const customProperties: Record<string, string> = {}
|
|
9
|
+
for (const property of properties) {
|
|
10
|
+
if (property.name.startsWith('--')) {
|
|
11
|
+
customProperties[property.name] = property.value
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
matches: [{ selector: '.test', properties: properties.filter((property) => !property.name.startsWith('--')) }],
|
|
16
|
+
customProperties,
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
describe('hasFlexOrGridDisplay', () => {
|
|
21
|
+
it('returns true for display: flex', () => {
|
|
22
|
+
expect(hasFlexOrGridDisplay(matcherDataFromCss('display: flex'))).toBe(true)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it('returns false for display: block', () => {
|
|
26
|
+
expect(hasFlexOrGridDisplay(matcherDataFromCss('display: block'))).toBe(false)
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
it('returns false when no properties', () => {
|
|
30
|
+
expect(hasFlexOrGridDisplay(matcherDataFromCss(''))).toBe(false)
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
it('returns false when var resolves to a non-flex/grid value', () => {
|
|
34
|
+
expect(hasFlexOrGridDisplay(matcherDataFromCss('display: var(--d); --d: block'))).toBe(false)
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
it('returns true when var resolves to grid', () => {
|
|
38
|
+
expect(hasFlexOrGridDisplay(matcherDataFromCss('display: var(--d); --d: grid'))).toBe(true)
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
it('returns true when var cannot be resolved', () => {
|
|
42
|
+
expect(hasFlexOrGridDisplay(matcherDataFromCss('display: var(--d)'))).toBe(true)
|
|
43
|
+
})
|
|
44
|
+
})
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { CSS_PROPERTIES } from '@wix/react-component-schema'
|
|
9
|
-
import type {
|
|
9
|
+
import type { MatchedCssData } from '../../css/types'
|
|
10
10
|
import type { ExtractedElement } from './core/tree-builder'
|
|
11
11
|
import type { CreateElementEvent, ReactExtractor } from './core/types'
|
|
12
12
|
|
|
@@ -186,6 +186,7 @@ export function getCssPropertiesForTag(tag: string, role?: string): string[] {
|
|
|
186
186
|
break
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
+
properties.push(CSS_PROPERTY_TYPE.display)
|
|
189
190
|
return properties
|
|
190
191
|
}
|
|
191
192
|
|
|
@@ -211,23 +212,85 @@ export function addGapProperty(existing: string[]): string[] {
|
|
|
211
212
|
return [...existing, CSS_PROPERTY_TYPE.gap]
|
|
212
213
|
}
|
|
213
214
|
|
|
215
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
216
|
+
// Display Value Resolution
|
|
217
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
218
|
+
|
|
219
|
+
const TAG_DEFAULT_DISPLAY: Record<string, string> = {
|
|
220
|
+
span: 'inline',
|
|
221
|
+
a: 'inline',
|
|
222
|
+
strong: 'inline',
|
|
223
|
+
em: 'inline',
|
|
224
|
+
b: 'inline',
|
|
225
|
+
i: 'inline',
|
|
226
|
+
label: 'inline',
|
|
227
|
+
img: 'inline',
|
|
228
|
+
input: 'inline',
|
|
229
|
+
select: 'inline',
|
|
230
|
+
textarea: 'inline',
|
|
231
|
+
button: 'inline-block',
|
|
232
|
+
li: 'list-item',
|
|
233
|
+
table: 'table',
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export function getDefaultDisplayForTag(tag: string): string {
|
|
237
|
+
return TAG_DEFAULT_DISPLAY[tag.toLowerCase()] ?? 'block'
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Resolves the current `display` value from matched CSS data, handling both
|
|
242
|
+
* literal values and CSS variable references.
|
|
243
|
+
* Returns the resolved value, or `undefined` if `display` is not declared
|
|
244
|
+
* or uses a variable that cannot be resolved.
|
|
245
|
+
*/
|
|
246
|
+
export function resolveDisplayValue(matcherData: MatchedCssData): string | undefined {
|
|
247
|
+
for (const match of matcherData.matches) {
|
|
248
|
+
for (const property of match.properties) {
|
|
249
|
+
if (property.name !== 'display') continue
|
|
250
|
+
|
|
251
|
+
if (!property.varRefs || property.varRefs.length === 0) {
|
|
252
|
+
return property.value
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
for (const varName of property.varRefs) {
|
|
256
|
+
const resolvedValue = matcherData.customProperties[varName]
|
|
257
|
+
if (resolvedValue !== undefined) return resolvedValue
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return undefined
|
|
262
|
+
}
|
|
263
|
+
|
|
214
264
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
215
265
|
// Gap Enrichment
|
|
216
266
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
217
267
|
|
|
218
268
|
const FLEX_GRID_DISPLAY_VALUES = new Set(['flex', 'grid', 'inline-flex', 'inline-grid'])
|
|
219
269
|
|
|
220
|
-
|
|
221
|
-
|
|
270
|
+
/**
|
|
271
|
+
* Returns true if display uses a CSS variable that cannot be resolved --
|
|
272
|
+
* we optimistically assume it could be flex/grid.
|
|
273
|
+
*/
|
|
274
|
+
function hasUnresolvableDisplayVar(matcherData: MatchedCssData): boolean {
|
|
275
|
+
for (const match of matcherData.matches) {
|
|
222
276
|
for (const property of match.properties) {
|
|
223
|
-
if (property.name
|
|
224
|
-
|
|
277
|
+
if (property.name !== 'display') continue
|
|
278
|
+
if (property.varRefs && property.varRefs.length > 0) {
|
|
279
|
+
for (const varName of property.varRefs) {
|
|
280
|
+
if (matcherData.customProperties[varName] === undefined) return true
|
|
281
|
+
}
|
|
225
282
|
}
|
|
226
283
|
}
|
|
227
284
|
}
|
|
228
285
|
return false
|
|
229
286
|
}
|
|
230
287
|
|
|
288
|
+
export function hasFlexOrGridDisplay(matcherData: MatchedCssData): boolean {
|
|
289
|
+
const displayValue = resolveDisplayValue(matcherData)
|
|
290
|
+
if (displayValue !== undefined) return FLEX_GRID_DISPLAY_VALUES.has(displayValue)
|
|
291
|
+
return hasUnresolvableDisplayVar(matcherData)
|
|
292
|
+
}
|
|
293
|
+
|
|
231
294
|
/**
|
|
232
295
|
* Walks the element tree and adds `gap` to relevant CSS properties
|
|
233
296
|
* for elements that have display: flex|grid and more than 1 child.
|
|
@@ -237,7 +300,7 @@ export function enrichGapProperties(elements: ExtractedElement[]): ExtractedElem
|
|
|
237
300
|
return elements.map((element) => {
|
|
238
301
|
if (element.children.length > 1) {
|
|
239
302
|
const matcherData = element.extractorData.get('css-matcher') as MatchedCssData | undefined
|
|
240
|
-
if (matcherData && hasFlexOrGridDisplay(matcherData
|
|
303
|
+
if (matcherData && hasFlexOrGridDisplay(matcherData)) {
|
|
241
304
|
const cssData = element.extractorData.get('css-properties') as CssPropertiesData | undefined
|
|
242
305
|
if (cssData) {
|
|
243
306
|
element.extractorData.set('css-properties', {
|
|
@@ -24,5 +24,10 @@ export type {
|
|
|
24
24
|
export { createPropTrackerExtractor } from './prop-tracker'
|
|
25
25
|
export type { PropTrackerData, PropTrackerExtractorState } from './prop-tracker'
|
|
26
26
|
|
|
27
|
-
export {
|
|
27
|
+
export {
|
|
28
|
+
createCssPropertiesExtractor,
|
|
29
|
+
enrichGapProperties,
|
|
30
|
+
resolveDisplayValue,
|
|
31
|
+
getDefaultDisplayForTag,
|
|
32
|
+
} from './css-properties'
|
|
28
33
|
export type { CssPropertiesData } from './css-properties'
|