@contentful/experience-design-system-extraction 2.35.1-dev-build-1f9cff15.0 → 2.35.1-dev-build-08991bee.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experience-design-system-extraction",
3
- "version": "2.35.1-dev-build-1f9cff15.0",
3
+ "version": "2.35.1-dev-build-08991bee.0",
4
4
  "description": "Component extraction engine for the Contentful Experience Design System SDK",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,4 +1,5 @@
1
1
  import { isStringLiteralUnion, isBooleanType, isStringType, isNumberType, isComplexType, } from './helpers/check-prop-types.js';
2
+ import { isDomPassThroughProp } from './helpers/detect-dom-props.js';
2
3
  /**
3
4
  * Deterministic pre-classification rule engine.
4
5
  * Applies rules in priority order and returns on the first match.
@@ -25,6 +26,16 @@ export function preClassifyProp(prop) {
25
26
  if (type.includes('Dispatch<') || type.includes('SetStateAction')) {
26
27
  return { category: 'exclude' };
27
28
  }
29
+ // Rule 6: DOM / a11y / framework pass-through props
30
+ if (isDomPassThroughProp(name)) {
31
+ return { category: 'exclude' };
32
+ }
33
+ // `name` is overloaded: form controls forward it to the DOM, while icons,
34
+ // flags, and animations often use it as an authorable semantic selector.
35
+ // Exclude only when the extractor retained concrete DOM provenance.
36
+ if (name === 'name' && prop.domAttribute) {
37
+ return { category: 'exclude' };
38
+ }
28
39
  // Rule 7: String literal union
29
40
  if (isStringLiteralUnion(type)) {
30
41
  return { category: 'design', cdfTypeHint: 'enum' };
@@ -102,13 +113,21 @@ export function preClassifyComponent(component) {
102
113
  if (result?.category === 'exclude') {
103
114
  return [];
104
115
  }
116
+ // Provenance is extraction-only evidence. Do not add it to the payload
117
+ // presented to downstream agents.
118
+ const { domAttribute: _domAttribute, ...authorableProp } = prop;
105
119
  if (prop.category) {
106
- return [prop];
120
+ return [authorableProp];
107
121
  }
108
122
  if (!result) {
109
- return [prop];
123
+ return [authorableProp];
110
124
  }
111
- return [{ ...prop, category: result.category }];
125
+ return [
126
+ {
127
+ ...authorableProp,
128
+ category: result.category,
129
+ },
130
+ ];
112
131
  });
113
132
  return { ...component, props };
114
133
  }
@@ -0,0 +1,2 @@
1
+ /** Returns true when the prop name is a DOM attribute, a11y attribute, or framework pass-through escape hatch. */
2
+ export declare function isDomPassThroughProp(name: string): boolean;
@@ -0,0 +1,63 @@
1
+ const DOM_PASS_THROUGH_PROPS = new Set([
2
+ // Bare HTML / framework styling pass-through
3
+ 'className',
4
+ 'class',
5
+ 'classes',
6
+ 'classNames',
7
+ 'rootClassName',
8
+ 'prefixCls',
9
+ 'style',
10
+ 'styles',
11
+ // Bare HTML attributes
12
+ 'id',
13
+ 'role',
14
+ 'tabIndex',
15
+ 'tabindex',
16
+ 'htmlFor',
17
+ 'for',
18
+ 'slot',
19
+ 'is',
20
+ 'lang',
21
+ 'dir',
22
+ 'hidden',
23
+ 'draggable',
24
+ 'spellCheck',
25
+ 'spellcheck',
26
+ 'contentEditable',
27
+ 'contenteditable',
28
+ 'inputMode',
29
+ 'inputmode',
30
+ 'autoComplete',
31
+ 'autocomplete',
32
+ 'autoFocus',
33
+ 'autofocus',
34
+ 'translate',
35
+ 'part',
36
+ 'exportparts',
37
+ 'aria',
38
+ // Framework theming / pass-through escape hatches — dev-facing, never marketer-configurable
39
+ 'dt',
40
+ 'pt',
41
+ 'ptOptions',
42
+ 'unstyled',
43
+ 'sx',
44
+ // Polymorphic component props — change rendered HTML/component, not marketer-visible behavior
45
+ 'as',
46
+ 'element',
47
+ 'component',
48
+ // QA / vendor test attributes
49
+ 'dataQa',
50
+ 'data-qa',
51
+ // Vue v-model internals — framework wiring, never marketer-configurable
52
+ 'modelValue',
53
+ 'modelModifiers',
54
+ ]);
55
+ /** Returns true when the prop name is a DOM attribute, a11y attribute, or framework pass-through escape hatch. */
56
+ export function isDomPassThroughProp(name) {
57
+ if (DOM_PASS_THROUGH_PROPS.has(name))
58
+ return true;
59
+ // aria-label, aria-hidden, ariaLabel, ariaHidden — both kebab and camel forms
60
+ if (/^aria[-A-Z]/.test(name))
61
+ return true;
62
+ return name.startsWith('data-');
63
+ }
@@ -2,11 +2,3 @@ export interface PreClassification {
2
2
  category: 'content' | 'design' | 'state' | 'exclude';
3
3
  cdfTypeHint?: 'string' | 'enum' | 'richtext' | 'media' | 'boolean';
4
4
  }
5
- export type PropBucket = 'custom' | 'dom-passthrough' | 'other';
6
- export interface PropBucketAssignment {
7
- component: string;
8
- source: string;
9
- customPropNames: string[];
10
- domPassthroughPropNames: string[];
11
- otherPropNames: string[];
12
- }
@@ -24,5 +24,4 @@ export { validateExtractedComponents, shouldExcludeDueToValidation, formatExclus
24
24
  export { parseImportedNames } from './extract/helpers/evidence/parse-source-imports.js';
25
25
  export { CONTENT_NAME_EXCEPTIONS, isReactNodeType, isArrayReactNodeType, shouldBeSlot, } from './extract/helpers/evidence/detect-slot-from-prop.js';
26
26
  export { preClassifyProp, preClassifyComponent } from './extract/services/classification/classify-component-props.js';
27
- export { bucketComponentProps, bucketComponentsProps, } from './extract/services/classification/bucket-component-props.js';
28
- export type { PreClassification, PropBucket, PropBucketAssignment } from './extract/types/classification.js';
27
+ export type { PreClassification } from './extract/types/classification.js';
package/dist/src/index.js CHANGED
@@ -25,4 +25,3 @@ export { parseImportedNames } from './extract/helpers/evidence/parse-source-impo
25
25
  export { CONTENT_NAME_EXCEPTIONS, isReactNodeType, isArrayReactNodeType, shouldBeSlot, } from './extract/helpers/evidence/detect-slot-from-prop.js';
26
26
  // Pre-classification
27
27
  export { preClassifyProp, preClassifyComponent } from './extract/services/classification/classify-component-props.js';
28
- export { bucketComponentProps, bucketComponentsProps, } from './extract/services/classification/bucket-component-props.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experience-design-system-extraction",
3
- "version": "2.35.1-dev-build-1f9cff15.0",
3
+ "version": "2.35.1-dev-build-08991bee.0",
4
4
  "description": "Component extraction engine for the Contentful Experience Design System SDK",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,4 +0,0 @@
1
- import type { RawComponentDefinition } from '../../types/component.js';
2
- import type { PropBucketAssignment } from '../../types/classification.js';
3
- export declare function bucketComponentProps(component: RawComponentDefinition): PropBucketAssignment;
4
- export declare function bucketComponentsProps(components: readonly RawComponentDefinition[]): PropBucketAssignment[];
@@ -1,29 +0,0 @@
1
- export function bucketComponentProps(component) {
2
- const customPropNames = [];
3
- const domPassthroughPropNames = [];
4
- const otherPropNames = [];
5
- for (const prop of component.props) {
6
- if (!prop.type.trim()) {
7
- otherPropNames.push(prop.name);
8
- }
9
- else if (prop.domAttribute === true) {
10
- domPassthroughPropNames.push(prop.name);
11
- }
12
- else {
13
- customPropNames.push(prop.name);
14
- }
15
- }
16
- const sortNames = (names) => names.toSorted((left, right) => left.localeCompare(right));
17
- return {
18
- component: component.name,
19
- source: component.source,
20
- customPropNames: sortNames(customPropNames),
21
- domPassthroughPropNames: sortNames(domPassthroughPropNames),
22
- otherPropNames: sortNames(otherPropNames),
23
- };
24
- }
25
- export function bucketComponentsProps(components) {
26
- return components
27
- .map(bucketComponentProps)
28
- .toSorted((left, right) => `${left.component}\u0000${left.source}`.localeCompare(`${right.component}\u0000${right.source}`));
29
- }