@wix/zero-config-implementation 1.45.0 → 1.47.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 +12785 -12723
- package/package.json +2 -2
- package/src/converters/to-editor-component.ts +36 -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.47.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": "3524e32da30b9a43b1f548d22b8e065abea7ce993f23ae0f52abc674"
|
|
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'
|
|
@@ -102,6 +104,7 @@ function buildElements(
|
|
|
102
104
|
inlineElement: {
|
|
103
105
|
selector: buildSelector(element),
|
|
104
106
|
displayName: formatDisplayName(element.name),
|
|
107
|
+
behaviors: { removable: true, selectable: false },
|
|
105
108
|
// Add data from inner element props if available
|
|
106
109
|
...(data && Object.keys(data).length > 0 && { data }),
|
|
107
110
|
// CSS properties from heuristic + matched CSS files
|
|
@@ -308,10 +311,24 @@ function getMatchedPropertyValues(element: ExtractedElement): Map<string, string
|
|
|
308
311
|
return values
|
|
309
312
|
}
|
|
310
313
|
|
|
314
|
+
const CSS_DISPLAY_TO_ENUM: Record<string, string> = {
|
|
315
|
+
'inline-block': 'inlineBlock',
|
|
316
|
+
'inline-flex': 'inlineFlex',
|
|
317
|
+
'inline-grid': 'inlineGrid',
|
|
318
|
+
'inline-table': 'inlineTable',
|
|
319
|
+
'list-item': 'listItem',
|
|
320
|
+
'flow-root': 'flowRoot',
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
function toDisplayEnumValue(cssValue: string): NonNullable<Display['displayValues']>[number] {
|
|
324
|
+
return (CSS_DISPLAY_TO_ENUM[cssValue] ?? cssValue) as NonNullable<Display['displayValues']>[number]
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const { CSS_PROPERTY_TYPE, DISPLAY_VALUE } = CSS_PROPERTIES
|
|
328
|
+
|
|
311
329
|
function buildCssProperties(element: ExtractedElement | undefined): Record<string, CssPropertyItem> {
|
|
312
330
|
const result: Record<string, CssPropertyItem> = {}
|
|
313
331
|
|
|
314
|
-
// Get the CSS properties decided by the heuristic
|
|
315
332
|
const cssData = element?.extractorData.get('css-properties') as CssPropertiesData | undefined
|
|
316
333
|
const decidedProperties = cssData?.relevant
|
|
317
334
|
if (!decidedProperties || decidedProperties.length === 0) {
|
|
@@ -319,12 +336,28 @@ function buildCssProperties(element: ExtractedElement | undefined): Record<strin
|
|
|
319
336
|
}
|
|
320
337
|
const cssPropertyValues = element ? getMatchedPropertyValues(element) : new Map<string, string>()
|
|
321
338
|
for (const propName of decidedProperties) {
|
|
339
|
+
if (propName === CSS_PROPERTY_TYPE.display && element) {
|
|
340
|
+
result[propName] = buildDisplayProperty(element)
|
|
341
|
+
continue
|
|
342
|
+
}
|
|
322
343
|
const defaultValue = cssPropertyValues.get(propName)
|
|
323
344
|
result[propName] = {
|
|
324
|
-
// Only include defaultValue if found in CSS files
|
|
325
345
|
...(defaultValue !== undefined && { defaultValue }),
|
|
326
346
|
}
|
|
327
347
|
}
|
|
328
348
|
|
|
329
349
|
return result
|
|
330
350
|
}
|
|
351
|
+
|
|
352
|
+
function buildDisplayProperty(element: ExtractedElement): CssPropertyItem {
|
|
353
|
+
const matcherData = element.extractorData.get('css-matcher') as MatchedCssData | undefined
|
|
354
|
+
const resolvedFromCss = matcherData ? resolveDisplayValue(matcherData) : undefined
|
|
355
|
+
const currentValue = resolvedFromCss ?? getDefaultDisplayForTag(element.tag)
|
|
356
|
+
const currentEnumValue = toDisplayEnumValue(currentValue)
|
|
357
|
+
|
|
358
|
+
return {
|
|
359
|
+
display: {
|
|
360
|
+
displayValues: [DISPLAY_VALUE.none, currentEnumValue],
|
|
361
|
+
},
|
|
362
|
+
}
|
|
363
|
+
}
|
|
@@ -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'
|