@patternfly/context-for-ai 1.2.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/README.md +615 -0
- package/codemod/ALL_COMPONENTS_REFERENCE.md +815 -0
- package/codemod/ATTRIBUTE_DECISION_LOGIC.md +320 -0
- package/codemod/README.md +400 -0
- package/codemod/add-semantic-attributes.sh +69 -0
- package/codemod/component-attributes-reference.json +129 -0
- package/codemod/example-after.tsx +51 -0
- package/codemod/example-before.tsx +19 -0
- package/codemod/static-inference.js +5015 -0
- package/codemod/transform.js +1108 -0
- package/dist/components/advanced/index.d.ts +2 -0
- package/dist/components/advanced/index.d.ts.map +1 -0
- package/dist/components/core/Button.d.ts +14 -0
- package/dist/components/core/Button.d.ts.map +1 -0
- package/dist/components/core/Link.d.ts +15 -0
- package/dist/components/core/Link.d.ts.map +1 -0
- package/dist/components/core/StarIcon.d.ts +15 -0
- package/dist/components/core/StarIcon.d.ts.map +1 -0
- package/dist/components/core/index.d.ts +4 -0
- package/dist/components/core/index.d.ts.map +1 -0
- package/dist/components/data-display/Card.d.ts +14 -0
- package/dist/components/data-display/Card.d.ts.map +1 -0
- package/dist/components/data-display/StatusBadge.d.ts +13 -0
- package/dist/components/data-display/StatusBadge.d.ts.map +1 -0
- package/dist/components/data-display/Tbody.d.ts +12 -0
- package/dist/components/data-display/Tbody.d.ts.map +1 -0
- package/dist/components/data-display/Td.d.ts +14 -0
- package/dist/components/data-display/Td.d.ts.map +1 -0
- package/dist/components/data-display/Th.d.ts +14 -0
- package/dist/components/data-display/Th.d.ts.map +1 -0
- package/dist/components/data-display/Thead.d.ts +12 -0
- package/dist/components/data-display/Thead.d.ts.map +1 -0
- package/dist/components/data-display/Tr.d.ts +16 -0
- package/dist/components/data-display/Tr.d.ts.map +1 -0
- package/dist/components/data-display/index.d.ts +8 -0
- package/dist/components/data-display/index.d.ts.map +1 -0
- package/dist/components/feedback/index.d.ts +2 -0
- package/dist/components/feedback/index.d.ts.map +1 -0
- package/dist/components/forms/Checkbox.d.ts +16 -0
- package/dist/components/forms/Checkbox.d.ts.map +1 -0
- package/dist/components/forms/Form.d.ts +12 -0
- package/dist/components/forms/Form.d.ts.map +1 -0
- package/dist/components/forms/Radio.d.ts +32 -0
- package/dist/components/forms/Radio.d.ts.map +1 -0
- package/dist/components/forms/Select.d.ts +33 -0
- package/dist/components/forms/Select.d.ts.map +1 -0
- package/dist/components/forms/Switch.d.ts +31 -0
- package/dist/components/forms/Switch.d.ts.map +1 -0
- package/dist/components/forms/TextArea.d.ts +29 -0
- package/dist/components/forms/TextArea.d.ts.map +1 -0
- package/dist/components/forms/TextInput.d.ts +29 -0
- package/dist/components/forms/TextInput.d.ts.map +1 -0
- package/dist/components/forms/index.d.ts +8 -0
- package/dist/components/forms/index.d.ts.map +1 -0
- package/dist/components/index.d.ts +9 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/layout/Flex.d.ts +16 -0
- package/dist/components/layout/Flex.d.ts.map +1 -0
- package/dist/components/layout/FlexItem.d.ts +16 -0
- package/dist/components/layout/FlexItem.d.ts.map +1 -0
- package/dist/components/layout/index.d.ts +3 -0
- package/dist/components/layout/index.d.ts.map +1 -0
- package/dist/components/navigation/DropdownItem.d.ts +8 -0
- package/dist/components/navigation/DropdownItem.d.ts.map +1 -0
- package/dist/components/navigation/MenuToggle.d.ts +8 -0
- package/dist/components/navigation/MenuToggle.d.ts.map +1 -0
- package/dist/components/navigation/index.d.ts +3 -0
- package/dist/components/navigation/index.d.ts.map +1 -0
- package/dist/components/overlay/Drawer.d.ts +12 -0
- package/dist/components/overlay/Drawer.d.ts.map +1 -0
- package/dist/components/overlay/Modal.d.ts +16 -0
- package/dist/components/overlay/Modal.d.ts.map +1 -0
- package/dist/components/overlay/index.d.ts +3 -0
- package/dist/components/overlay/index.d.ts.map +1 -0
- package/dist/context/SemanticContext.d.ts +28 -0
- package/dist/context/SemanticContext.d.ts.map +1 -0
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/useAccessibility.d.ts +13 -0
- package/dist/hooks/useAccessibility.d.ts.map +1 -0
- package/dist/hooks/useSemanticMetadata.d.ts +9 -0
- package/dist/hooks/useSemanticMetadata.d.ts.map +1 -0
- package/dist/index.d.ts +574 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.esm.js +1362 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +1426 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +47 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/utils/accessibility.d.ts +16 -0
- package/dist/utils/accessibility.d.ts.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/inference.d.ts +136 -0
- package/dist/utils/inference.d.ts.map +1 -0
- package/dist/utils/metadata.d.ts +17 -0
- package/dist/utils/metadata.d.ts.map +1 -0
- package/package.json +104 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1426 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var React = require('react');
|
|
5
|
+
var reactCore = require('@patternfly/react-core');
|
|
6
|
+
var reactTable = require('@patternfly/react-table');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Inference utilities for automatically determining semantic properties
|
|
10
|
+
* from PatternFly component props
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Determine if a component is a visual parent (requires user action to see contents)
|
|
14
|
+
* vs a wrapper/structure (always visible)
|
|
15
|
+
*/
|
|
16
|
+
const isVisualParent = (componentName) => {
|
|
17
|
+
const visualParents = [
|
|
18
|
+
'modal', 'drawer', 'popover', 'tooltip', // Overlays
|
|
19
|
+
'wizardstep', 'wizard', 'tab', 'accordion', // Navigation containers
|
|
20
|
+
'expandable', 'dropdown', 'menu', 'menutoggle' // Expandable containers
|
|
21
|
+
];
|
|
22
|
+
return visualParents.includes(componentName.toLowerCase());
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Infer button action from PatternFly variant and props
|
|
26
|
+
* Returns both behavior (what it does) and styling (how it looks)
|
|
27
|
+
*/
|
|
28
|
+
const inferButtonAction = (variant, href, onClick, target) => {
|
|
29
|
+
// Determine behavior - what the button DOES
|
|
30
|
+
let behaviorType = 'default';
|
|
31
|
+
if (href) {
|
|
32
|
+
// Has href - it's a link
|
|
33
|
+
if (href.startsWith('http'))
|
|
34
|
+
behaviorType = 'external';
|
|
35
|
+
else if (target === '_blank')
|
|
36
|
+
behaviorType = 'external';
|
|
37
|
+
else if (href.startsWith('/'))
|
|
38
|
+
behaviorType = 'navigation';
|
|
39
|
+
else
|
|
40
|
+
behaviorType = 'navigation';
|
|
41
|
+
}
|
|
42
|
+
else if (onClick) {
|
|
43
|
+
// Has onClick but no href - it's an action
|
|
44
|
+
behaviorType = 'action';
|
|
45
|
+
}
|
|
46
|
+
// Determine styling - visual importance/appearance
|
|
47
|
+
let styleVariant = 'secondary';
|
|
48
|
+
switch (variant) {
|
|
49
|
+
case 'primary':
|
|
50
|
+
styleVariant = 'primary';
|
|
51
|
+
break;
|
|
52
|
+
case 'danger':
|
|
53
|
+
styleVariant = 'destructive';
|
|
54
|
+
break;
|
|
55
|
+
case 'control':
|
|
56
|
+
styleVariant = 'toggle';
|
|
57
|
+
break;
|
|
58
|
+
case 'secondary':
|
|
59
|
+
case 'tertiary':
|
|
60
|
+
case 'plain':
|
|
61
|
+
case 'link':
|
|
62
|
+
styleVariant = variant;
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
type: behaviorType,
|
|
67
|
+
variant: styleVariant
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Infer input purpose from type
|
|
72
|
+
*/
|
|
73
|
+
const inferInputPurpose = (type) => {
|
|
74
|
+
switch (type) {
|
|
75
|
+
case 'email':
|
|
76
|
+
return 'email-input';
|
|
77
|
+
case 'password':
|
|
78
|
+
return 'password-input';
|
|
79
|
+
case 'search':
|
|
80
|
+
return 'search-input';
|
|
81
|
+
case 'tel':
|
|
82
|
+
return 'phone-input';
|
|
83
|
+
case 'url':
|
|
84
|
+
return 'url-input';
|
|
85
|
+
case 'number':
|
|
86
|
+
return 'numeric-input';
|
|
87
|
+
case 'date':
|
|
88
|
+
case 'datetime-local':
|
|
89
|
+
case 'time':
|
|
90
|
+
return 'date-time-input';
|
|
91
|
+
case 'text':
|
|
92
|
+
default:
|
|
93
|
+
return 'text-input';
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Infer alert severity
|
|
98
|
+
*/
|
|
99
|
+
const inferAlertSeverity = (variant) => {
|
|
100
|
+
switch (variant) {
|
|
101
|
+
case 'success':
|
|
102
|
+
return 'success';
|
|
103
|
+
case 'danger':
|
|
104
|
+
return 'error';
|
|
105
|
+
case 'warning':
|
|
106
|
+
return 'warning';
|
|
107
|
+
case 'info':
|
|
108
|
+
case 'default':
|
|
109
|
+
default:
|
|
110
|
+
return 'info';
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
/**
|
|
114
|
+
* Infer context from parent or usage
|
|
115
|
+
*/
|
|
116
|
+
const inferContext = (props) => {
|
|
117
|
+
if (props.onClick || props.onSubmit)
|
|
118
|
+
return 'active';
|
|
119
|
+
if (props.isDisabled)
|
|
120
|
+
return 'disabled';
|
|
121
|
+
if (props.isReadOnly)
|
|
122
|
+
return 'readonly';
|
|
123
|
+
return 'default';
|
|
124
|
+
};
|
|
125
|
+
/**
|
|
126
|
+
* Infer card purpose from PatternFly props
|
|
127
|
+
*/
|
|
128
|
+
const inferCardPurpose = (props) => {
|
|
129
|
+
// Interactive cards
|
|
130
|
+
if (props.isSelectable)
|
|
131
|
+
return 'selection-panel';
|
|
132
|
+
if (props.isClickable)
|
|
133
|
+
return 'action-panel';
|
|
134
|
+
if (props.isExpanded !== undefined)
|
|
135
|
+
return 'expandable-content';
|
|
136
|
+
// Layout-based cards
|
|
137
|
+
if (props.isCompact)
|
|
138
|
+
return 'data-summary';
|
|
139
|
+
if (props.isPlain)
|
|
140
|
+
return 'content-display';
|
|
141
|
+
// Content-based cards (based on children analysis)
|
|
142
|
+
if (props.children) {
|
|
143
|
+
const childrenStr = props.children.toString().toLowerCase();
|
|
144
|
+
if (childrenStr.includes('logo') || childrenStr.includes('brand'))
|
|
145
|
+
return 'brand-display';
|
|
146
|
+
if (childrenStr.includes('chart') || childrenStr.includes('graph'))
|
|
147
|
+
return 'data-visualization';
|
|
148
|
+
if (childrenStr.includes('form') || childrenStr.includes('input'))
|
|
149
|
+
return 'form-container';
|
|
150
|
+
if (childrenStr.includes('table') || childrenStr.includes('list'))
|
|
151
|
+
return 'data-display';
|
|
152
|
+
}
|
|
153
|
+
return 'content-display';
|
|
154
|
+
};
|
|
155
|
+
/**
|
|
156
|
+
* Infer modal purpose from props
|
|
157
|
+
*/
|
|
158
|
+
const inferModalPurpose = (props) => {
|
|
159
|
+
if (props.variant === 'small')
|
|
160
|
+
return 'confirmation';
|
|
161
|
+
if (props.variant === 'large')
|
|
162
|
+
return 'form';
|
|
163
|
+
return 'information';
|
|
164
|
+
};
|
|
165
|
+
/**
|
|
166
|
+
* Infer accessibility features from props
|
|
167
|
+
*/
|
|
168
|
+
const inferAccessibilityFeatures = (props) => {
|
|
169
|
+
const features = ['keyboard-navigable'];
|
|
170
|
+
if (props['aria-label'] || props['aria-labelledby']) {
|
|
171
|
+
features.push('screen-reader-friendly');
|
|
172
|
+
}
|
|
173
|
+
if (props.autoFocus) {
|
|
174
|
+
features.push('auto-focus');
|
|
175
|
+
}
|
|
176
|
+
if (props.role) {
|
|
177
|
+
features.push('semantic-role');
|
|
178
|
+
}
|
|
179
|
+
return features;
|
|
180
|
+
};
|
|
181
|
+
/**
|
|
182
|
+
* Infer usage patterns from component type and props
|
|
183
|
+
*/
|
|
184
|
+
const inferUsagePatterns = (componentType, props) => {
|
|
185
|
+
const patterns = ['user-interface'];
|
|
186
|
+
// Component-specific patterns
|
|
187
|
+
switch (componentType.toLowerCase()) {
|
|
188
|
+
case 'button':
|
|
189
|
+
if (props.type === 'submit')
|
|
190
|
+
patterns.push('form-submission');
|
|
191
|
+
if (props.onClick)
|
|
192
|
+
patterns.push('user-interaction');
|
|
193
|
+
break;
|
|
194
|
+
case 'textinput':
|
|
195
|
+
case 'textarea':
|
|
196
|
+
patterns.push('data-entry', 'form-input');
|
|
197
|
+
if (props.validated === 'error')
|
|
198
|
+
patterns.push('validation');
|
|
199
|
+
break;
|
|
200
|
+
case 'select':
|
|
201
|
+
patterns.push('data-entry', 'selection');
|
|
202
|
+
break;
|
|
203
|
+
case 'checkbox':
|
|
204
|
+
case 'radio':
|
|
205
|
+
patterns.push('user-selection', 'form-input');
|
|
206
|
+
break;
|
|
207
|
+
case 'modal':
|
|
208
|
+
patterns.push('user-interaction', 'workflow-step');
|
|
209
|
+
break;
|
|
210
|
+
case 'card':
|
|
211
|
+
patterns.push('content-organization', 'data-presentation');
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
return patterns;
|
|
215
|
+
};
|
|
216
|
+
/**
|
|
217
|
+
* Generate comprehensive metadata from props
|
|
218
|
+
*/
|
|
219
|
+
const generateMetadataFromProps = (componentName, props) => {
|
|
220
|
+
return {
|
|
221
|
+
description: `${componentName} component`,
|
|
222
|
+
category: inferCategory(componentName),
|
|
223
|
+
accessibility: inferAccessibilityFeatures(props),
|
|
224
|
+
usage: inferUsagePatterns(componentName, props)
|
|
225
|
+
};
|
|
226
|
+
};
|
|
227
|
+
/**
|
|
228
|
+
* Infer card content type from PatternFly props and children
|
|
229
|
+
*/
|
|
230
|
+
const inferCardContentType = (props) => {
|
|
231
|
+
// Interactive states - keep them separate
|
|
232
|
+
if (props.isSelectable)
|
|
233
|
+
return 'selectable';
|
|
234
|
+
if (props.isClickable)
|
|
235
|
+
return 'clickable';
|
|
236
|
+
if (props.isExpanded !== undefined)
|
|
237
|
+
return 'expandable';
|
|
238
|
+
// Content analysis based on children
|
|
239
|
+
if (props.children) {
|
|
240
|
+
const childrenStr = props.children.toString().toLowerCase();
|
|
241
|
+
// Logo content (media cards should only contain logos)
|
|
242
|
+
if (childrenStr.includes('logo') || childrenStr.includes('brand')) {
|
|
243
|
+
return 'logo';
|
|
244
|
+
}
|
|
245
|
+
// Data content
|
|
246
|
+
if (childrenStr.includes('table') || childrenStr.includes('chart') || childrenStr.includes('graph') ||
|
|
247
|
+
childrenStr.includes('metric') || childrenStr.includes('stat')) {
|
|
248
|
+
return 'data';
|
|
249
|
+
}
|
|
250
|
+
// Form content
|
|
251
|
+
if (childrenStr.includes('form') || childrenStr.includes('input') || childrenStr.includes('button')) {
|
|
252
|
+
return 'interactive';
|
|
253
|
+
}
|
|
254
|
+
// Text content
|
|
255
|
+
if (childrenStr.includes('text') || childrenStr.includes('description') || childrenStr.includes('paragraph')) {
|
|
256
|
+
return 'text';
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return 'mixed'; // Default fallback
|
|
260
|
+
};
|
|
261
|
+
/**
|
|
262
|
+
* Infer card interactive state from PatternFly props
|
|
263
|
+
*/
|
|
264
|
+
const inferCardInteractiveState = (props) => {
|
|
265
|
+
// Interactive states
|
|
266
|
+
if (props.isSelectable) {
|
|
267
|
+
if (props.isSelected)
|
|
268
|
+
return 'selected';
|
|
269
|
+
return 'selectable';
|
|
270
|
+
}
|
|
271
|
+
if (props.isClickable) {
|
|
272
|
+
if (props.isDisabled)
|
|
273
|
+
return 'disabled-clickable';
|
|
274
|
+
return 'clickable';
|
|
275
|
+
}
|
|
276
|
+
if (props.isExpanded !== undefined) {
|
|
277
|
+
if (props.isExpanded)
|
|
278
|
+
return 'expanded';
|
|
279
|
+
return 'collapsed';
|
|
280
|
+
}
|
|
281
|
+
// Default state
|
|
282
|
+
return 'static';
|
|
283
|
+
};
|
|
284
|
+
/**
|
|
285
|
+
* Infer modal interaction type
|
|
286
|
+
*/
|
|
287
|
+
const inferModalInteractionType = (isOpen) => {
|
|
288
|
+
return isOpen ? 'blocking' : 'non-blocking';
|
|
289
|
+
};
|
|
290
|
+
/**
|
|
291
|
+
* Infer select purpose
|
|
292
|
+
*/
|
|
293
|
+
const inferSelectPurpose = () => {
|
|
294
|
+
return 'data-entry';
|
|
295
|
+
};
|
|
296
|
+
/**
|
|
297
|
+
* Infer select selection type
|
|
298
|
+
*/
|
|
299
|
+
const inferSelectSelectionType = (variant) => {
|
|
300
|
+
return variant === 'typeahead' ? 'typeahead' : 'single';
|
|
301
|
+
};
|
|
302
|
+
/**
|
|
303
|
+
* Infer radio purpose
|
|
304
|
+
*/
|
|
305
|
+
const inferRadioPurpose = () => {
|
|
306
|
+
return 'option-selection';
|
|
307
|
+
};
|
|
308
|
+
/**
|
|
309
|
+
* Infer radio group context
|
|
310
|
+
*/
|
|
311
|
+
const inferRadioGroupContext = (name) => {
|
|
312
|
+
return name || 'unknown-group';
|
|
313
|
+
};
|
|
314
|
+
/**
|
|
315
|
+
* Infer switch purpose
|
|
316
|
+
*/
|
|
317
|
+
const inferSwitchPurpose = () => {
|
|
318
|
+
return 'setting';
|
|
319
|
+
};
|
|
320
|
+
/**
|
|
321
|
+
* Infer switch toggle target
|
|
322
|
+
*/
|
|
323
|
+
const inferSwitchToggleTarget = () => {
|
|
324
|
+
return 'feature';
|
|
325
|
+
};
|
|
326
|
+
/**
|
|
327
|
+
* Infer textarea purpose
|
|
328
|
+
*/
|
|
329
|
+
const inferTextAreaPurpose = () => {
|
|
330
|
+
return 'content';
|
|
331
|
+
};
|
|
332
|
+
/**
|
|
333
|
+
* Infer textarea content type
|
|
334
|
+
*/
|
|
335
|
+
const inferTextAreaContentType = () => {
|
|
336
|
+
return 'plain-text';
|
|
337
|
+
};
|
|
338
|
+
/**
|
|
339
|
+
* Infer checkbox purpose
|
|
340
|
+
*/
|
|
341
|
+
const inferCheckboxPurpose = (isChecked) => {
|
|
342
|
+
return isChecked !== undefined ? 'selection' : 'form-input';
|
|
343
|
+
};
|
|
344
|
+
/**
|
|
345
|
+
* Infer link purpose
|
|
346
|
+
*/
|
|
347
|
+
const inferLinkPurpose = (href, children) => {
|
|
348
|
+
if (href?.startsWith('http'))
|
|
349
|
+
return 'external';
|
|
350
|
+
if (href === '#')
|
|
351
|
+
return 'action';
|
|
352
|
+
if (href?.includes('download'))
|
|
353
|
+
return 'download';
|
|
354
|
+
if (children?.toString().toLowerCase().includes('launch'))
|
|
355
|
+
return 'launch';
|
|
356
|
+
return 'navigation';
|
|
357
|
+
};
|
|
358
|
+
/**
|
|
359
|
+
* Infer star icon purpose
|
|
360
|
+
*/
|
|
361
|
+
const inferStarIconPurpose = (isFavorited) => {
|
|
362
|
+
return isFavorited !== undefined ? 'favorite-toggle' : 'rating';
|
|
363
|
+
};
|
|
364
|
+
/**
|
|
365
|
+
* Infer validation context
|
|
366
|
+
*/
|
|
367
|
+
const inferValidationContext = (isRequired) => {
|
|
368
|
+
return isRequired ? 'required' : 'optional';
|
|
369
|
+
};
|
|
370
|
+
/**
|
|
371
|
+
* Infer form context (default for most form components)
|
|
372
|
+
*/
|
|
373
|
+
const inferFormContext = () => {
|
|
374
|
+
return 'form';
|
|
375
|
+
};
|
|
376
|
+
/**
|
|
377
|
+
* Infer settings context (default for switches)
|
|
378
|
+
*/
|
|
379
|
+
const inferSettingsContext = () => {
|
|
380
|
+
return 'settings';
|
|
381
|
+
};
|
|
382
|
+
/**
|
|
383
|
+
* Infer status badge type from content
|
|
384
|
+
*/
|
|
385
|
+
const inferStatusBadgeType = (content) => {
|
|
386
|
+
const lower = content?.toLowerCase() || '';
|
|
387
|
+
if (lower.includes('ready'))
|
|
388
|
+
return 'ready';
|
|
389
|
+
if (lower.includes('success'))
|
|
390
|
+
return 'success';
|
|
391
|
+
if (lower.includes('warning'))
|
|
392
|
+
return 'warning';
|
|
393
|
+
if (lower.includes('error') || lower.includes('fail'))
|
|
394
|
+
return 'error';
|
|
395
|
+
if (lower.includes('pending'))
|
|
396
|
+
return 'pending';
|
|
397
|
+
return 'info';
|
|
398
|
+
};
|
|
399
|
+
/**
|
|
400
|
+
* Infer status badge purpose
|
|
401
|
+
*/
|
|
402
|
+
const inferStatusBadgePurpose = () => {
|
|
403
|
+
return 'status-indicator';
|
|
404
|
+
};
|
|
405
|
+
/**
|
|
406
|
+
* Infer category from component name
|
|
407
|
+
* Category describes WHAT the component IS, not what it DOES (that's the action)
|
|
408
|
+
*/
|
|
409
|
+
const inferCategory = (componentName) => {
|
|
410
|
+
const name = componentName.toLowerCase();
|
|
411
|
+
// Component type categorization
|
|
412
|
+
if (name === 'button') {
|
|
413
|
+
return 'button';
|
|
414
|
+
}
|
|
415
|
+
if (['textinput', 'textarea', 'select', 'radio', 'checkbox', 'switch'].includes(name)) {
|
|
416
|
+
return 'forms';
|
|
417
|
+
}
|
|
418
|
+
if (['nav', 'breadcrumb', 'tabs', 'pagination', 'masthead'].includes(name)) {
|
|
419
|
+
return 'navigation';
|
|
420
|
+
}
|
|
421
|
+
if (['card', 'table', 'datalist', 'label', 'badge'].includes(name)) {
|
|
422
|
+
return 'data-display';
|
|
423
|
+
}
|
|
424
|
+
if (['alert', 'banner', 'toast', 'progress', 'spinner'].includes(name)) {
|
|
425
|
+
return 'feedback';
|
|
426
|
+
}
|
|
427
|
+
if (['modal', 'drawer', 'popover', 'tooltip'].includes(name)) {
|
|
428
|
+
return 'overlay';
|
|
429
|
+
}
|
|
430
|
+
if (['flex', 'grid', 'stack', 'panel'].includes(name)) {
|
|
431
|
+
return 'layout';
|
|
432
|
+
}
|
|
433
|
+
return 'data-display';
|
|
434
|
+
};
|
|
435
|
+
|
|
436
|
+
const SemanticContext = React.createContext(undefined);
|
|
437
|
+
const useSemanticContext = () => {
|
|
438
|
+
const context = React.useContext(SemanticContext);
|
|
439
|
+
if (!context) {
|
|
440
|
+
throw new Error('useSemanticContext must be used within a SemanticProvider');
|
|
441
|
+
}
|
|
442
|
+
return context;
|
|
443
|
+
};
|
|
444
|
+
const SemanticProvider = ({ children }) => {
|
|
445
|
+
const [contextStack, setContextStack] = React.useState([]);
|
|
446
|
+
const addContext = (context, semanticName, isQualified) => {
|
|
447
|
+
// Auto-detect if not specified
|
|
448
|
+
const qualified = isQualified !== undefined ? isQualified : isVisualParent(context);
|
|
449
|
+
setContextStack(prev => [...prev, {
|
|
450
|
+
name: context,
|
|
451
|
+
semanticName: semanticName || context, // Use semantic name if provided, otherwise fallback to context
|
|
452
|
+
isQualified: qualified
|
|
453
|
+
}]);
|
|
454
|
+
};
|
|
455
|
+
const removeContext = () => {
|
|
456
|
+
setContextStack(prev => prev.slice(0, -1));
|
|
457
|
+
};
|
|
458
|
+
const clearContext = () => {
|
|
459
|
+
setContextStack([]);
|
|
460
|
+
};
|
|
461
|
+
const getHierarchy = () => {
|
|
462
|
+
const allSemanticNames = contextStack.map(c => c.semanticName);
|
|
463
|
+
const qualifiedOnly = contextStack.filter(c => c.isQualified).map(c => c.semanticName);
|
|
464
|
+
const wrappersOnly = contextStack.filter(c => !c.isQualified).map(c => c.semanticName);
|
|
465
|
+
return {
|
|
466
|
+
fullPath: allSemanticNames.length > 0 ? allSemanticNames.join(' > ') : '',
|
|
467
|
+
qualifiedParents: qualifiedOnly,
|
|
468
|
+
wrappers: wrappersOnly,
|
|
469
|
+
immediateParent: qualifiedOnly.length > 0 ? qualifiedOnly[qualifiedOnly.length - 1] : '',
|
|
470
|
+
immediateWrapper: wrappersOnly.length > 0 ? wrappersOnly[wrappersOnly.length - 1] : '',
|
|
471
|
+
depth: qualifiedOnly.length
|
|
472
|
+
};
|
|
473
|
+
};
|
|
474
|
+
return (jsxRuntime.jsx(SemanticContext.Provider, { value: {
|
|
475
|
+
contextStack,
|
|
476
|
+
addContext,
|
|
477
|
+
removeContext,
|
|
478
|
+
getHierarchy,
|
|
479
|
+
clearContext,
|
|
480
|
+
}, children: children }));
|
|
481
|
+
};
|
|
482
|
+
|
|
483
|
+
/** Button - PatternFly Button wrapper with semantic metadata for AI tooling */
|
|
484
|
+
const Button = ({ semanticRole, aiMetadata: _aiMetadata, action, context, target, semanticName, children, variant, onClick, isDisabled, ...props }) => {
|
|
485
|
+
// Get hierarchy from context (optional - gracefully handles no provider)
|
|
486
|
+
let hierarchy;
|
|
487
|
+
let addContext, removeContext;
|
|
488
|
+
try {
|
|
489
|
+
const semanticContext = useSemanticContext();
|
|
490
|
+
hierarchy = semanticContext.getHierarchy();
|
|
491
|
+
addContext = semanticContext.addContext;
|
|
492
|
+
removeContext = semanticContext.removeContext;
|
|
493
|
+
}
|
|
494
|
+
catch {
|
|
495
|
+
hierarchy = { fullPath: '', qualifiedParents: [], wrappers: [], immediateParent: '', immediateWrapper: '', depth: 0 };
|
|
496
|
+
addContext = () => { };
|
|
497
|
+
removeContext = () => { };
|
|
498
|
+
}
|
|
499
|
+
// Auto-infer semantic properties from PatternFly props
|
|
500
|
+
const inferredAction = inferButtonAction(variant, props.href, onClick, target);
|
|
501
|
+
const actionType = action || inferredAction.type;
|
|
502
|
+
const actionVariant = inferredAction.variant;
|
|
503
|
+
const inferredContext = context || inferContext({ onClick, isDisabled, ...props });
|
|
504
|
+
// Generate semantic role (combines category, action, context into one)
|
|
505
|
+
const role = semanticRole || `button-${actionType}-${inferredContext}`;
|
|
506
|
+
// Generate semantic name: wrapper > parent > action type
|
|
507
|
+
// Button acts on wrapper (if exists), otherwise parent, otherwise standalone
|
|
508
|
+
const componentName = semanticName || (() => {
|
|
509
|
+
// Format action type: "action" → "Action", "navigation" → "Navigation", "external" → "External Link"
|
|
510
|
+
// Treat "default" as "Action"
|
|
511
|
+
let actionLabel;
|
|
512
|
+
if (actionType === 'default') {
|
|
513
|
+
actionLabel = 'Action';
|
|
514
|
+
}
|
|
515
|
+
else if (actionType === 'external') {
|
|
516
|
+
actionLabel = 'External Link';
|
|
517
|
+
}
|
|
518
|
+
else {
|
|
519
|
+
actionLabel = actionType.charAt(0).toUpperCase() + actionType.slice(1);
|
|
520
|
+
}
|
|
521
|
+
// Priority: wrapper (immediate context) > parent > standalone
|
|
522
|
+
if (hierarchy.immediateWrapper) {
|
|
523
|
+
return `${hierarchy.immediateWrapper} ${actionLabel}`;
|
|
524
|
+
}
|
|
525
|
+
else if (hierarchy.immediateParent) {
|
|
526
|
+
return `${hierarchy.immediateParent} ${actionLabel}`;
|
|
527
|
+
}
|
|
528
|
+
// Otherwise just the action label
|
|
529
|
+
return actionLabel;
|
|
530
|
+
})();
|
|
531
|
+
// Register button with its semantic name in context (for modal triggering)
|
|
532
|
+
React.useEffect(() => {
|
|
533
|
+
addContext('Button', componentName, false); // false = not a visual parent
|
|
534
|
+
return () => removeContext();
|
|
535
|
+
}, [addContext, removeContext, componentName]);
|
|
536
|
+
const consequence = actionVariant === 'destructive' ? 'destructive-permanent' : 'safe';
|
|
537
|
+
const affectsParent = target === 'parent-modal' || target === 'parent-form';
|
|
538
|
+
return (jsxRuntime.jsx(reactCore.Button, { ...props, variant: variant, onClick: onClick, isDisabled: isDisabled, "data-semantic-name": componentName, "data-semantic-path": hierarchy.fullPath ? `${hierarchy.fullPath} > ${componentName}` : componentName, "data-parent": hierarchy.immediateParent || 'none', "data-wrapper": hierarchy.immediateWrapper || 'none', "data-num-parents": hierarchy.depth, "data-semantic-role": role, "data-action-variant": actionVariant, "data-target": target || 'default', "data-consequence": consequence, "data-affects-parent": affectsParent, children: children }));
|
|
539
|
+
};
|
|
540
|
+
|
|
541
|
+
/** Link - HTML anchor wrapper with semantic metadata for AI tooling */
|
|
542
|
+
const Link = ({ semanticName, semanticRole, aiMetadata, purpose, context, target, htmlTarget, children, href, onClick, ...props }) => {
|
|
543
|
+
// Get hierarchy from context (optional - gracefully handles no provider)
|
|
544
|
+
let hierarchy;
|
|
545
|
+
try {
|
|
546
|
+
const semanticContext = useSemanticContext();
|
|
547
|
+
hierarchy = semanticContext.getHierarchy();
|
|
548
|
+
}
|
|
549
|
+
catch {
|
|
550
|
+
hierarchy = { fullPath: '', qualifiedParents: [], wrappers: [], immediateParent: '', immediateWrapper: '', depth: 0 };
|
|
551
|
+
}
|
|
552
|
+
// Auto-infer semantic properties from props
|
|
553
|
+
const inferredPurpose = purpose || inferLinkPurpose(href, children);
|
|
554
|
+
const inferredContext = context || (onClick ? inferContext({ onClick }) : 'content');
|
|
555
|
+
const componentName = semanticName || 'Link';
|
|
556
|
+
// Generate semantic role and AI metadata
|
|
557
|
+
const role = semanticRole || `link-${inferredPurpose}-${inferredContext}`;
|
|
558
|
+
const metadata = aiMetadata || {
|
|
559
|
+
description: `${inferredPurpose} link for ${inferredContext} context`,
|
|
560
|
+
category: inferCategory('Link'),
|
|
561
|
+
usage: [`${inferredContext}-${inferredPurpose}`, 'user-interaction'],
|
|
562
|
+
hierarchy,
|
|
563
|
+
action: {
|
|
564
|
+
type: inferredPurpose,
|
|
565
|
+
target: target || 'default'
|
|
566
|
+
}
|
|
567
|
+
};
|
|
568
|
+
return (jsxRuntime.jsx("a", { ...props, href: href, onClick: onClick, target: htmlTarget, "data-semantic-name": componentName, "data-semantic-path": hierarchy.fullPath ? `${hierarchy.fullPath} > ${componentName}` : componentName, "data-parent": hierarchy.immediateParent || 'none', "data-wrapper": hierarchy.immediateWrapper || 'none', "data-num-parents": hierarchy.depth, "data-semantic-role": role, "data-ai-metadata": JSON.stringify(metadata), "data-purpose": inferredPurpose, "data-target": target || 'default', "data-context": inferredContext, children: children }));
|
|
569
|
+
};
|
|
570
|
+
|
|
571
|
+
/** StarIcon - HTML span wrapper with semantic metadata for AI tooling */
|
|
572
|
+
const StarIcon = ({ semanticName, semanticRole, aiMetadata, purpose, context, children, isFavorited, onClick, ...props }) => {
|
|
573
|
+
// Auto-infer semantic properties from props
|
|
574
|
+
const inferredPurpose = purpose || inferStarIconPurpose(isFavorited);
|
|
575
|
+
const inferredContext = context || (onClick ? inferContext({ onClick }) : 'display');
|
|
576
|
+
// Generate semantic role and AI metadata
|
|
577
|
+
const role = semanticRole || `star-icon-${inferredPurpose}-${inferredContext}`;
|
|
578
|
+
const metadata = aiMetadata || {
|
|
579
|
+
description: `${inferredPurpose} star icon for ${inferredContext} context`,
|
|
580
|
+
category: 'forms',
|
|
581
|
+
complexity: 'simple',
|
|
582
|
+
usage: [`${inferredContext}-${inferredPurpose}`, 'user-interaction']
|
|
583
|
+
};
|
|
584
|
+
// Default semantic name if not provided
|
|
585
|
+
const defaultSemanticName = semanticName || 'Row Item';
|
|
586
|
+
return (jsxRuntime.jsx("span", { ...props, onClick: onClick, "data-semantic-name": defaultSemanticName, "data-semantic-role": role, "data-ai-metadata": JSON.stringify(metadata), "data-purpose": inferredPurpose, "data-context": inferredContext, "data-is-favorited": isFavorited, children: children }));
|
|
587
|
+
};
|
|
588
|
+
|
|
589
|
+
/** Form - PatternFly Form wrapper with semantic metadata for AI tooling */
|
|
590
|
+
const Form = ({ semanticName, semanticRole, purpose, children, ...props }) => {
|
|
591
|
+
// Register as wrapper (not a visual parent) in semantic context
|
|
592
|
+
const { addContext, removeContext } = useSemanticContext();
|
|
593
|
+
React.useEffect(() => {
|
|
594
|
+
addContext('Form', undefined, false); // false = wrapper (always visible)
|
|
595
|
+
return () => removeContext();
|
|
596
|
+
}, [addContext, removeContext]);
|
|
597
|
+
// Get hierarchy from context
|
|
598
|
+
let hierarchy;
|
|
599
|
+
try {
|
|
600
|
+
const semanticContext = useSemanticContext();
|
|
601
|
+
hierarchy = semanticContext.getHierarchy();
|
|
602
|
+
}
|
|
603
|
+
catch {
|
|
604
|
+
hierarchy = { fullPath: '', qualifiedParents: [], wrappers: [], immediateParent: '', immediateWrapper: '', depth: 0 };
|
|
605
|
+
}
|
|
606
|
+
// Auto-infer purpose from context if not provided
|
|
607
|
+
const inferredPurpose = purpose || 'edit';
|
|
608
|
+
// Generate semantic role
|
|
609
|
+
const role = semanticRole || `form-${inferredPurpose}`;
|
|
610
|
+
// Default semantic name if not provided
|
|
611
|
+
const componentName = semanticName || 'Form';
|
|
612
|
+
return (jsxRuntime.jsx(reactCore.Form, { ...props, "data-semantic-name": componentName, "data-semantic-path": hierarchy.fullPath ? `${hierarchy.fullPath} > ${componentName}` : componentName, "data-parent": hierarchy.immediateParent || 'none', "data-wrapper": hierarchy.immediateWrapper || 'none', "data-num-parents": hierarchy.depth, "data-semantic-role": role, "data-purpose": inferredPurpose, children: children }));
|
|
613
|
+
};
|
|
614
|
+
|
|
615
|
+
/** Checkbox - PatternFly Checkbox wrapper with semantic metadata for AI tooling */
|
|
616
|
+
const Checkbox = ({ semanticName, semanticRole, aiMetadata, purpose, context, children, isChecked, onChange, id, ...props }) => {
|
|
617
|
+
// Auto-infer semantic properties from PatternFly props
|
|
618
|
+
const inferredPurpose = purpose || inferCheckboxPurpose(isChecked);
|
|
619
|
+
const inferredContext = context || (onChange ? inferContext({ onChange }) : inferFormContext());
|
|
620
|
+
// Generate semantic role and AI metadata
|
|
621
|
+
const role = semanticRole || `checkbox-${inferredPurpose}-${inferredContext}`;
|
|
622
|
+
const metadata = aiMetadata || {
|
|
623
|
+
description: `${inferredPurpose} checkbox for ${inferredContext} context`,
|
|
624
|
+
category: inferCategory('Checkbox'),
|
|
625
|
+
usage: [`${inferredContext}-${inferredPurpose}`, 'user-interaction']
|
|
626
|
+
};
|
|
627
|
+
// Default semantic name if not provided
|
|
628
|
+
const defaultSemanticName = semanticName || 'Row Item';
|
|
629
|
+
return (jsxRuntime.jsx(reactCore.Checkbox, { ...props, id: id, isChecked: isChecked, onChange: onChange, "data-semantic-name": defaultSemanticName, "data-semantic-role": role, "data-ai-metadata": JSON.stringify(metadata), "data-purpose": inferredPurpose, "data-context": inferredContext, children: children }));
|
|
630
|
+
};
|
|
631
|
+
|
|
632
|
+
/**
|
|
633
|
+
* TextInput - PatternFly TextInput wrapper with semantic metadata for AI tooling
|
|
634
|
+
*
|
|
635
|
+
* @example
|
|
636
|
+
* ```tsx
|
|
637
|
+
* <TextInput
|
|
638
|
+
* type="email"
|
|
639
|
+
* purpose="email-input"
|
|
640
|
+
* context="form"
|
|
641
|
+
* placeholder="Enter your email"
|
|
642
|
+
* value={email}
|
|
643
|
+
* onChange={handleChange}
|
|
644
|
+
* />
|
|
645
|
+
* ```
|
|
646
|
+
*/
|
|
647
|
+
const TextInput = React.forwardRef(({ semanticName, semanticRole, aiMetadata, purpose, context, validationContext, type = 'text', validated, isRequired, ...props }, ref) => {
|
|
648
|
+
// 1. Auto-infer semantic properties from PatternFly props
|
|
649
|
+
const inferredPurpose = purpose || inferInputPurpose(type);
|
|
650
|
+
const inferredContext = context || inferFormContext();
|
|
651
|
+
const inferredValidation = validationContext || inferValidationContext(isRequired);
|
|
652
|
+
// 2. Generate semantic role and AI metadata
|
|
653
|
+
const role = semanticRole || `textinput-${inferredPurpose}-${inferredContext}`;
|
|
654
|
+
const metadata = aiMetadata || {
|
|
655
|
+
...generateMetadataFromProps('TextInput', { type, validated, isRequired, ...props }),
|
|
656
|
+
description: `${inferredPurpose} for ${inferredContext} context`,
|
|
657
|
+
usage: ['data-entry', 'form-input', 'user-interaction']
|
|
658
|
+
};
|
|
659
|
+
// 3. Default semantic name
|
|
660
|
+
const defaultSemanticName = semanticName || 'TextInput';
|
|
661
|
+
// 4. Render PatternFly component with semantic data attributes
|
|
662
|
+
return (jsxRuntime.jsx(reactCore.TextInput, { ...props, ref: ref, type: type, validated: validated, isRequired: isRequired, "data-semantic-name": defaultSemanticName, "data-semantic-role": role, "data-ai-metadata": JSON.stringify(metadata), "data-purpose": inferredPurpose, "data-context": inferredContext, "data-validation-context": inferredValidation }));
|
|
663
|
+
});
|
|
664
|
+
TextInput.displayName = 'TextInput';
|
|
665
|
+
|
|
666
|
+
/**
|
|
667
|
+
* TextArea - PatternFly TextArea wrapper with semantic metadata for AI tooling
|
|
668
|
+
*
|
|
669
|
+
* @example
|
|
670
|
+
* ```tsx
|
|
671
|
+
* <TextArea
|
|
672
|
+
* purpose="comment"
|
|
673
|
+
* context="comment-section"
|
|
674
|
+
* placeholder="Add your comment..."
|
|
675
|
+
* value={comment}
|
|
676
|
+
* onChange={handleChange}
|
|
677
|
+
* resizeOrientation="vertical"
|
|
678
|
+
* />
|
|
679
|
+
* ```
|
|
680
|
+
*/
|
|
681
|
+
const TextArea = React.forwardRef(({ semanticName, semanticRole, aiMetadata, purpose, context, contentType, validated, isRequired, ...props }, ref) => {
|
|
682
|
+
// 1. Auto-infer semantic properties
|
|
683
|
+
const inferredPurpose = purpose || inferTextAreaPurpose();
|
|
684
|
+
const inferredContext = context || inferFormContext();
|
|
685
|
+
const inferredContentType = contentType || inferTextAreaContentType();
|
|
686
|
+
// 2. Generate semantic role and AI metadata
|
|
687
|
+
const role = semanticRole || `textarea-${inferredPurpose}-${inferredContext}`;
|
|
688
|
+
const metadata = aiMetadata || {
|
|
689
|
+
...generateMetadataFromProps('TextArea', { validated, isRequired, ...props }),
|
|
690
|
+
description: `${inferredPurpose} textarea for ${inferredContext} containing ${inferredContentType}`,
|
|
691
|
+
usage: ['data-entry', 'long-form-input', 'user-interaction']
|
|
692
|
+
};
|
|
693
|
+
// 3. Default semantic name
|
|
694
|
+
const defaultSemanticName = semanticName || 'TextArea';
|
|
695
|
+
// 4. Render PatternFly component with semantic data attributes
|
|
696
|
+
return (jsxRuntime.jsx(reactCore.TextArea, { ...props, ref: ref, validated: validated, isRequired: isRequired, "data-semantic-name": defaultSemanticName, "data-semantic-role": role, "data-ai-metadata": JSON.stringify(metadata), "data-purpose": inferredPurpose, "data-context": inferredContext, "data-content-type": inferredContentType }));
|
|
697
|
+
});
|
|
698
|
+
TextArea.displayName = 'TextArea';
|
|
699
|
+
|
|
700
|
+
/**
|
|
701
|
+
* Select - PatternFly Select wrapper with semantic metadata for AI tooling
|
|
702
|
+
*
|
|
703
|
+
* @example
|
|
704
|
+
* ```tsx
|
|
705
|
+
* <Select
|
|
706
|
+
* purpose="category-selection"
|
|
707
|
+
* context="form"
|
|
708
|
+
* isOpen={isOpen}
|
|
709
|
+
* onToggle={handleToggle}
|
|
710
|
+
* selections={selected}
|
|
711
|
+
* onSelect={handleSelect}
|
|
712
|
+
* >
|
|
713
|
+
* <SelectOption value="option1" />
|
|
714
|
+
* <SelectOption value="option2" />
|
|
715
|
+
* </Select>
|
|
716
|
+
* ```
|
|
717
|
+
*/
|
|
718
|
+
const Select = ({ semanticName, semanticRole, aiMetadata, purpose, context, selectionType, variant, children, ...props }) => {
|
|
719
|
+
// 1. Auto-infer semantic properties
|
|
720
|
+
const inferredPurpose = purpose || inferSelectPurpose();
|
|
721
|
+
const inferredContext = context || inferFormContext();
|
|
722
|
+
const inferredSelectionType = selectionType || inferSelectSelectionType(variant);
|
|
723
|
+
// 2. Generate semantic role and AI metadata
|
|
724
|
+
const role = semanticRole || `select-${inferredPurpose}-${inferredContext}`;
|
|
725
|
+
const metadata = aiMetadata || {
|
|
726
|
+
...generateMetadataFromProps('Select', { variant, ...props }),
|
|
727
|
+
description: `${inferredPurpose} select with ${inferredSelectionType} selection for ${inferredContext}`,
|
|
728
|
+
usage: ['data-entry', 'user-selection', 'user-interaction']
|
|
729
|
+
};
|
|
730
|
+
// 3. Default semantic name
|
|
731
|
+
const defaultSemanticName = semanticName || 'Select';
|
|
732
|
+
// 4. Render PatternFly component with semantic data attributes
|
|
733
|
+
return (jsxRuntime.jsx(reactCore.Select, { ...props, variant: variant, "data-semantic-name": defaultSemanticName, "data-semantic-role": role, "data-ai-metadata": JSON.stringify(metadata), "data-purpose": inferredPurpose, "data-context": inferredContext, "data-selection-type": inferredSelectionType, children: children }));
|
|
734
|
+
};
|
|
735
|
+
|
|
736
|
+
/**
|
|
737
|
+
* Radio - PatternFly Radio wrapper with semantic metadata for AI tooling
|
|
738
|
+
*
|
|
739
|
+
* @example
|
|
740
|
+
* ```tsx
|
|
741
|
+
* <Radio
|
|
742
|
+
* purpose="preference"
|
|
743
|
+
* context="settings"
|
|
744
|
+
* groupContext="theme-selection"
|
|
745
|
+
* name="theme"
|
|
746
|
+
* id="theme-light"
|
|
747
|
+
* label="Light Theme"
|
|
748
|
+
* isChecked={theme === 'light'}
|
|
749
|
+
* onChange={handleChange}
|
|
750
|
+
* />
|
|
751
|
+
* ```
|
|
752
|
+
*/
|
|
753
|
+
const Radio = ({ semanticName, semanticRole, aiMetadata, purpose, context, groupContext, name, isChecked, isDisabled, children, ...props }) => {
|
|
754
|
+
// 1. Auto-infer semantic properties
|
|
755
|
+
const inferredPurpose = purpose || inferRadioPurpose();
|
|
756
|
+
const inferredContext = context || inferFormContext();
|
|
757
|
+
const inferredGroupContext = groupContext || inferRadioGroupContext(name);
|
|
758
|
+
// 2. Generate semantic role and AI metadata
|
|
759
|
+
const role = semanticRole || `radio-${inferredPurpose}-${inferredContext}`;
|
|
760
|
+
const metadata = aiMetadata || {
|
|
761
|
+
...generateMetadataFromProps('Radio', { name, isChecked, isDisabled, ...props }),
|
|
762
|
+
description: `${inferredPurpose} radio button in ${inferredGroupContext} group for ${inferredContext}`,
|
|
763
|
+
usage: ['user-selection', 'form-input', 'user-interaction']
|
|
764
|
+
};
|
|
765
|
+
// 3. Default semantic name
|
|
766
|
+
const defaultSemanticName = semanticName || 'Radio';
|
|
767
|
+
// 4. Render PatternFly component with semantic data attributes
|
|
768
|
+
return (jsxRuntime.jsx(reactCore.Radio, { ...props, name: name, isChecked: isChecked, isDisabled: isDisabled, "data-semantic-name": defaultSemanticName, "data-semantic-role": role, "data-ai-metadata": JSON.stringify(metadata), "data-purpose": inferredPurpose, "data-context": inferredContext, "data-group-context": inferredGroupContext, children: children }));
|
|
769
|
+
};
|
|
770
|
+
|
|
771
|
+
/**
|
|
772
|
+
* Switch - PatternFly Switch wrapper with semantic metadata for AI tooling
|
|
773
|
+
*
|
|
774
|
+
* @example
|
|
775
|
+
* ```tsx
|
|
776
|
+
* <Switch
|
|
777
|
+
* purpose="feature-toggle"
|
|
778
|
+
* context="settings"
|
|
779
|
+
* toggleTarget="feature"
|
|
780
|
+
* id="notifications"
|
|
781
|
+
* label="Enable notifications"
|
|
782
|
+
* isChecked={notificationsEnabled}
|
|
783
|
+
* onChange={handleToggle}
|
|
784
|
+
* />
|
|
785
|
+
* ```
|
|
786
|
+
*/
|
|
787
|
+
const Switch = ({ semanticName, semanticRole, aiMetadata, purpose, context, toggleTarget, isChecked, isDisabled, children, ...props }) => {
|
|
788
|
+
// 1. Auto-infer semantic properties
|
|
789
|
+
const inferredPurpose = purpose || inferSwitchPurpose();
|
|
790
|
+
const inferredContext = context || inferSettingsContext();
|
|
791
|
+
const inferredToggleTarget = toggleTarget || inferSwitchToggleTarget();
|
|
792
|
+
// 2. Generate semantic role and AI metadata
|
|
793
|
+
const role = semanticRole || `switch-${inferredPurpose}-${inferredContext}`;
|
|
794
|
+
const metadata = aiMetadata || {
|
|
795
|
+
...generateMetadataFromProps('Switch', { isChecked, isDisabled, ...props }),
|
|
796
|
+
description: `${inferredPurpose} switch for toggling ${inferredToggleTarget} in ${inferredContext}`,
|
|
797
|
+
usage: ['user-interaction', 'toggle-control', 'settings-control']
|
|
798
|
+
};
|
|
799
|
+
// 3. Default semantic name
|
|
800
|
+
const defaultSemanticName = semanticName || 'Switch';
|
|
801
|
+
// 4. Render PatternFly component with semantic data attributes
|
|
802
|
+
return (jsxRuntime.jsx(reactCore.Switch, { ...props, isChecked: isChecked, isDisabled: isDisabled, "data-semantic-name": defaultSemanticName, "data-semantic-role": role, "data-ai-metadata": JSON.stringify(metadata), "data-purpose": inferredPurpose, "data-context": inferredContext, "data-toggle-target": inferredToggleTarget, children: children }));
|
|
803
|
+
};
|
|
804
|
+
|
|
805
|
+
/** Card - PatternFly Card wrapper with semantic metadata for AI tooling */
|
|
806
|
+
const Card = ({ semanticName, semanticRole, aiMetadata: _aiMetadata, purpose, contentType, children, isSelectable, isClickable, isExpanded, isCompact, isSelected, isDisabled, ...props }) => {
|
|
807
|
+
// Get hierarchy from context (optional - gracefully handles no provider)
|
|
808
|
+
let hierarchy;
|
|
809
|
+
let addContext, removeContext;
|
|
810
|
+
try {
|
|
811
|
+
const semanticContext = useSemanticContext();
|
|
812
|
+
hierarchy = semanticContext.getHierarchy();
|
|
813
|
+
addContext = semanticContext.addContext;
|
|
814
|
+
removeContext = semanticContext.removeContext;
|
|
815
|
+
}
|
|
816
|
+
catch {
|
|
817
|
+
hierarchy = { fullPath: '', qualifiedParents: [], wrappers: [], immediateParent: '', immediateWrapper: '', depth: 0 };
|
|
818
|
+
addContext = () => { };
|
|
819
|
+
removeContext = () => { };
|
|
820
|
+
}
|
|
821
|
+
// Auto-infer semantic properties from PatternFly props and children
|
|
822
|
+
const inferredPurpose = purpose || inferCardPurpose({ isSelectable, isClickable, isExpanded, isCompact, children });
|
|
823
|
+
const inferredContentType = contentType || inferCardContentType({ isSelectable, isClickable, isExpanded, children });
|
|
824
|
+
const inferredInteractiveState = inferCardInteractiveState({ isSelectable, isClickable, isExpanded, isSelected, isDisabled });
|
|
825
|
+
// Generate semantic role
|
|
826
|
+
const role = semanticRole || `card-${inferredPurpose}-${inferredContentType}`;
|
|
827
|
+
// Generate semantic name: wrapper > parent > standalone
|
|
828
|
+
// Card acts on wrapper (if exists), otherwise parent, otherwise standalone
|
|
829
|
+
const componentName = semanticName || (() => {
|
|
830
|
+
// Priority: wrapper (immediate context) > parent > standalone
|
|
831
|
+
if (hierarchy.immediateWrapper) {
|
|
832
|
+
return `${hierarchy.immediateWrapper} Card`;
|
|
833
|
+
}
|
|
834
|
+
else if (hierarchy.immediateParent) {
|
|
835
|
+
return `${hierarchy.immediateParent} Card`;
|
|
836
|
+
}
|
|
837
|
+
// Otherwise just "Card"
|
|
838
|
+
return 'Card';
|
|
839
|
+
})();
|
|
840
|
+
// Register card with its semantic name in context
|
|
841
|
+
React.useEffect(() => {
|
|
842
|
+
addContext('Card', componentName, false); // false = wrapper (always visible)
|
|
843
|
+
return () => removeContext();
|
|
844
|
+
}, [addContext, removeContext, componentName]);
|
|
845
|
+
return (jsxRuntime.jsx(reactCore.Card, { ...props, isSelectable: isSelectable, isClickable: isClickable, isExpanded: isExpanded, isCompact: isCompact, isSelected: isSelected, isDisabled: isDisabled, "data-semantic-name": componentName, "data-semantic-path": hierarchy.fullPath ? `${hierarchy.fullPath} > ${componentName}` : componentName, "data-parent": hierarchy.immediateParent || 'none', "data-wrapper": hierarchy.immediateWrapper || 'none', "data-num-parents": hierarchy.depth, "data-semantic-role": role, "data-purpose": inferredPurpose, "data-content-type": inferredContentType, "data-interactive-state": inferredInteractiveState, children: children }));
|
|
846
|
+
};
|
|
847
|
+
|
|
848
|
+
/** StatusBadge - HTML span wrapper with semantic metadata for AI tooling */
|
|
849
|
+
const StatusBadge = ({ semanticName, semanticRole, aiMetadata, purpose, statusType, children, ...props }) => {
|
|
850
|
+
// Auto-infer semantic properties from content
|
|
851
|
+
const content = children?.toString();
|
|
852
|
+
const inferredStatusType = statusType || inferStatusBadgeType(content);
|
|
853
|
+
const inferredPurpose = purpose || inferStatusBadgePurpose();
|
|
854
|
+
// Generate semantic role and AI metadata
|
|
855
|
+
const role = semanticRole || `status-badge-${inferredPurpose}-${inferredStatusType}`;
|
|
856
|
+
const metadata = aiMetadata || {
|
|
857
|
+
description: `${inferredPurpose} showing ${inferredStatusType} status`,
|
|
858
|
+
category: 'data-display',
|
|
859
|
+
complexity: 'simple',
|
|
860
|
+
usage: [`${inferredPurpose}`, 'status-display', 'state-indication']
|
|
861
|
+
};
|
|
862
|
+
// Default semantic name if not provided
|
|
863
|
+
const defaultSemanticName = semanticName || 'Row Item';
|
|
864
|
+
return (jsxRuntime.jsx("span", { ...props, "data-semantic-name": defaultSemanticName, "data-semantic-role": role, "data-ai-metadata": JSON.stringify(metadata), "data-purpose": inferredPurpose, "data-status-type": inferredStatusType, children: children }));
|
|
865
|
+
};
|
|
866
|
+
|
|
867
|
+
/** Tbody - PatternFly Table Body wrapper with semantic metadata for AI tooling */
|
|
868
|
+
const Tbody = ({ semanticName, semanticRole, aiMetadata, purpose, children, ...props }) => {
|
|
869
|
+
// Auto-infer semantic properties from children content
|
|
870
|
+
const inferredPurpose = purpose || (React.Children.toArray(children).some(child => React.isValidElement(child) && React.Children.toArray(child.props?.children).some(cell => React.isValidElement(cell) && cell.props?.children?.toString().toLowerCase().includes('select'))) ? 'selectable-rows' :
|
|
871
|
+
React.Children.toArray(children).some(child => React.isValidElement(child) && React.Children.toArray(child.props?.children).some(cell => React.isValidElement(cell) && cell.props?.children?.toString().toLowerCase().includes('action'))) ? 'action-rows' :
|
|
872
|
+
React.Children.toArray(children).some(child => React.isValidElement(child) && React.Children.toArray(child.props?.children).some(cell => React.isValidElement(cell) && typeof cell.props?.children === 'object')) ? 'mixed-content' : 'data-rows');
|
|
873
|
+
// Generate semantic role and AI metadata
|
|
874
|
+
const role = semanticRole || `table-body-section-${inferredPurpose}`;
|
|
875
|
+
const metadata = aiMetadata || {
|
|
876
|
+
description: `Table body section with ${inferredPurpose}`,
|
|
877
|
+
category: 'data-display',
|
|
878
|
+
complexity: 'moderate',
|
|
879
|
+
usage: [`table-${inferredPurpose}`, 'data-presentation', 'row-content']
|
|
880
|
+
};
|
|
881
|
+
// Default semantic name if not provided
|
|
882
|
+
const defaultSemanticName = semanticName || 'Body Section';
|
|
883
|
+
return (jsxRuntime.jsx(reactTable.Tbody, { ...props, "data-semantic-name": defaultSemanticName, "data-semantic-role": role, "data-ai-metadata": JSON.stringify(metadata), "data-purpose": inferredPurpose, children: children }));
|
|
884
|
+
};
|
|
885
|
+
|
|
886
|
+
/** Td - PatternFly Table Data wrapper with semantic metadata for AI tooling */
|
|
887
|
+
const Td = ({ semanticName, semanticRole, aiMetadata, purpose, dataType, children, ...props }) => {
|
|
888
|
+
// Auto-infer semantic properties from PatternFly props and content
|
|
889
|
+
const inferredPurpose = purpose || (React.Children.toArray(children).some(child => React.isValidElement(child) && child.type?.toString().includes('Button')) ? 'action-cell' :
|
|
890
|
+
React.Children.toArray(children).some(child => React.isValidElement(child) && child.type?.toString().includes('Checkbox')) ? 'selectable-cell' :
|
|
891
|
+
children?.toString().toLowerCase().includes('status') ? 'status-cell' : 'data-cell');
|
|
892
|
+
// Simple data type inference based on content
|
|
893
|
+
const inferredDataType = dataType || (typeof children === 'number' ? 'number' :
|
|
894
|
+
children?.toString().match(/^\d{4}-\d{2}-\d{2}/) ? 'date' :
|
|
895
|
+
children?.toString().toLowerCase() === 'true' ||
|
|
896
|
+
children?.toString().toLowerCase() === 'false' ? 'boolean' :
|
|
897
|
+
React.Children.toArray(children).some(child => React.isValidElement(child) && child.type?.toString().includes('Button')) ? 'action' : 'text');
|
|
898
|
+
// Generate semantic role and AI metadata
|
|
899
|
+
const role = semanticRole || `table-cell-${inferredPurpose}-${inferredDataType}`;
|
|
900
|
+
const metadata = aiMetadata || {
|
|
901
|
+
description: `${inferredPurpose} containing ${inferredDataType} data`,
|
|
902
|
+
category: 'data-display',
|
|
903
|
+
complexity: 'simple',
|
|
904
|
+
usage: [`table-${inferredPurpose}`, 'data-presentation', 'row-content']
|
|
905
|
+
};
|
|
906
|
+
// Default semantic name if not provided
|
|
907
|
+
const defaultSemanticName = semanticName || 'Row Item';
|
|
908
|
+
return (jsxRuntime.jsx(reactTable.Td, { ...props, "data-semantic-name": defaultSemanticName, "data-semantic-role": role, "data-ai-metadata": JSON.stringify(metadata), "data-purpose": inferredPurpose, "data-data-type": inferredDataType, children: children }));
|
|
909
|
+
};
|
|
910
|
+
|
|
911
|
+
/** Th - PatternFly Table Header wrapper with semantic metadata for AI tooling */
|
|
912
|
+
const Th = ({ semanticName, semanticRole, aiMetadata, purpose, dataType, children, sort, ...props }) => {
|
|
913
|
+
// Auto-infer semantic properties from PatternFly props
|
|
914
|
+
const inferredPurpose = purpose || (sort ? 'sortable-header' :
|
|
915
|
+
children?.toString().toLowerCase().includes('select') ? 'selectable-header' :
|
|
916
|
+
children?.toString().toLowerCase().includes('action') ? 'action-header' : 'column-header');
|
|
917
|
+
// Simple data type inference based on content
|
|
918
|
+
const inferredDataType = dataType || (children?.toString().toLowerCase().includes('date') ? 'date' :
|
|
919
|
+
children?.toString().toLowerCase().includes('id') ||
|
|
920
|
+
children?.toString().toLowerCase().includes('count') ? 'number' :
|
|
921
|
+
children?.toString().toLowerCase().includes('action') ? 'action' : 'text');
|
|
922
|
+
// Generate semantic role and AI metadata
|
|
923
|
+
const role = semanticRole || `table-header-${inferredPurpose}-${inferredDataType}`;
|
|
924
|
+
const metadata = aiMetadata || {
|
|
925
|
+
description: `${inferredPurpose} for ${inferredDataType} data`,
|
|
926
|
+
category: 'data-display',
|
|
927
|
+
complexity: 'simple',
|
|
928
|
+
usage: [`table-${inferredPurpose}`, 'data-organization', 'column-definition']
|
|
929
|
+
};
|
|
930
|
+
// Always use 'Th' for component type identification (for validation)
|
|
931
|
+
// Store custom semantic name separately as instance name
|
|
932
|
+
const componentType = 'Th';
|
|
933
|
+
const instanceName = semanticName;
|
|
934
|
+
return (jsxRuntime.jsx(reactTable.Th, { ...props, sort: sort, "data-semantic-name": componentType, "data-instance-name": instanceName, "data-semantic-role": role, "data-ai-metadata": JSON.stringify(metadata), "data-purpose": inferredPurpose, "data-data-type": inferredDataType, children: children }));
|
|
935
|
+
};
|
|
936
|
+
|
|
937
|
+
/** Thead - PatternFly Table Header wrapper with semantic metadata for AI tooling */
|
|
938
|
+
const Thead = ({ semanticName, semanticRole, aiMetadata, purpose, children, ...props }) => {
|
|
939
|
+
// Auto-infer semantic properties from children content
|
|
940
|
+
const inferredPurpose = purpose || (React.Children.toArray(children).some(child => React.isValidElement(child) && child.props?.sort) ? 'sortable-headers' :
|
|
941
|
+
React.Children.toArray(children).some(child => React.isValidElement(child) && child.props?.children?.toString().toLowerCase().includes('select')) ? 'selectable-headers' :
|
|
942
|
+
React.Children.toArray(children).some(child => React.isValidElement(child) && child.props?.children?.toString().toLowerCase().includes('action')) ? 'action-headers' : 'column-definition');
|
|
943
|
+
// Generate semantic role and AI metadata
|
|
944
|
+
const role = semanticRole || `table-header-section-${inferredPurpose}`;
|
|
945
|
+
const metadata = aiMetadata || {
|
|
946
|
+
description: `Table header section with ${inferredPurpose}`,
|
|
947
|
+
category: 'data-display',
|
|
948
|
+
complexity: 'moderate',
|
|
949
|
+
usage: [`table-${inferredPurpose}`, 'data-organization', 'column-structure']
|
|
950
|
+
};
|
|
951
|
+
// Default semantic name if not provided
|
|
952
|
+
const defaultSemanticName = semanticName || 'Header Section';
|
|
953
|
+
return (jsxRuntime.jsx(reactTable.Thead, { ...props, "data-semantic-name": defaultSemanticName, "data-semantic-role": role, "data-ai-metadata": JSON.stringify(metadata), "data-purpose": inferredPurpose, children: children }));
|
|
954
|
+
};
|
|
955
|
+
|
|
956
|
+
/** Tr - PatternFly Table Row wrapper with semantic metadata for AI tooling */
|
|
957
|
+
const Tr = ({ semanticName, semanticRole, aiMetadata, purpose, interactionType, rowState, children, isClickable, isSelectable, isExpanded, isStriped, ...props }) => {
|
|
958
|
+
// Auto-infer semantic properties from PatternFly props and content
|
|
959
|
+
const inferredPurpose = purpose || (React.Children.toArray(children).some(child => React.isValidElement(child) &&
|
|
960
|
+
React.Children.toArray(child.props?.children).some(cell => React.isValidElement(cell) && cell.type?.toString().includes('Th'))) ? 'header-row' :
|
|
961
|
+
React.Children.toArray(children).some(child => React.isValidElement(child) &&
|
|
962
|
+
React.Children.toArray(child.props?.children).some(cell => React.isValidElement(cell) && cell.type?.toString().includes('Checkbox'))) ? 'selectable-row' :
|
|
963
|
+
isExpanded ? 'expandable-row' :
|
|
964
|
+
React.Children.toArray(children).some(child => React.isValidElement(child) &&
|
|
965
|
+
React.Children.toArray(child.props?.children).some(cell => React.isValidElement(cell) && cell.type?.toString().includes('Button'))) ? 'action-row' : 'data-row');
|
|
966
|
+
const inferredInteractionType = interactionType || (isClickable ? 'clickable' :
|
|
967
|
+
isSelectable ? 'selectable' :
|
|
968
|
+
isExpanded !== undefined ? 'expandable' :
|
|
969
|
+
'static');
|
|
970
|
+
const inferredRowState = rowState || (isExpanded ? 'expanded' :
|
|
971
|
+
isSelectable ? 'selected' :
|
|
972
|
+
isStriped ? 'highlighted' :
|
|
973
|
+
'normal');
|
|
974
|
+
// Generate semantic role and AI metadata
|
|
975
|
+
const role = semanticRole || `table-row-${inferredPurpose}-${inferredInteractionType}`;
|
|
976
|
+
const metadata = aiMetadata || {
|
|
977
|
+
description: `${inferredPurpose} with ${inferredInteractionType} interaction`,
|
|
978
|
+
category: 'data-display',
|
|
979
|
+
complexity: inferredInteractionType === 'static' ? 'simple' : 'medium',
|
|
980
|
+
usage: [`table-${inferredPurpose}`, 'row-interaction', 'data-presentation'],
|
|
981
|
+
interactionType: inferredInteractionType,
|
|
982
|
+
rowState: inferredRowState,
|
|
983
|
+
isStriped: isStriped || false
|
|
984
|
+
};
|
|
985
|
+
// Default semantic name if not provided
|
|
986
|
+
const defaultSemanticName = semanticName || 'Table Row';
|
|
987
|
+
return (jsxRuntime.jsx(reactTable.Tr, { ...props, isClickable: isClickable, isSelectable: isSelectable, isExpanded: isExpanded, isStriped: isStriped, "data-semantic-name": defaultSemanticName, "data-semantic-role": role, "data-ai-metadata": JSON.stringify(metadata), "data-purpose": inferredPurpose, "data-interaction-type": inferredInteractionType, "data-row-state": inferredRowState, children: children }));
|
|
988
|
+
};
|
|
989
|
+
|
|
990
|
+
/** Flex - PatternFly Flex wrapper with semantic metadata for AI tooling */
|
|
991
|
+
const Flex = ({ semanticName, semanticRole, aiMetadata, purpose, layoutType, alignmentContext, children, direction, justifyContent, alignItems, alignSelf, flex, spaceItems, gap, columnGap, rowGap, order, component, display, ...props }) => {
|
|
992
|
+
// Auto-infer semantic properties from PatternFly props
|
|
993
|
+
const inferredPurpose = purpose || (justifyContent?.default === 'justifyContentSpaceBetween' ? 'toolbar' :
|
|
994
|
+
justifyContent?.default === 'justifyContentCenter' ? 'content' :
|
|
995
|
+
spaceItems ? 'action-group' :
|
|
996
|
+
'layout');
|
|
997
|
+
const inferredLayoutType = layoutType || (direction?.default === 'column' ? 'column' :
|
|
998
|
+
direction?.lg ? 'responsive' :
|
|
999
|
+
'row');
|
|
1000
|
+
const inferredAlignmentContext = alignmentContext || (alignItems?.default === 'alignItemsCenter' ? 'center' :
|
|
1001
|
+
alignItems?.default === 'alignItemsFlexEnd' ? 'end' :
|
|
1002
|
+
alignItems?.default === 'alignItemsFlexStart' ? 'start' :
|
|
1003
|
+
alignItems?.default === 'alignItemsStretch' ? 'stretch' :
|
|
1004
|
+
alignItems?.default === 'alignItemsBaseline' ? 'baseline' :
|
|
1005
|
+
'start');
|
|
1006
|
+
// Generate semantic role and AI metadata
|
|
1007
|
+
const role = semanticRole || `flex-${inferredPurpose}-${inferredLayoutType}`;
|
|
1008
|
+
const metadata = aiMetadata || {
|
|
1009
|
+
description: `${inferredPurpose} flex container with ${inferredLayoutType} layout`,
|
|
1010
|
+
category: 'layout',
|
|
1011
|
+
complexity: inferredLayoutType === 'responsive' ? 'medium' : 'simple',
|
|
1012
|
+
usage: [`${inferredPurpose}-layout`, `${inferredLayoutType}-container`, 'responsive-design'],
|
|
1013
|
+
alignment: inferredAlignmentContext,
|
|
1014
|
+
layoutDirection: direction?.default || 'row'
|
|
1015
|
+
};
|
|
1016
|
+
// Default semantic name if not provided
|
|
1017
|
+
const defaultSemanticName = semanticName || 'Flex Container';
|
|
1018
|
+
return (jsxRuntime.jsx(reactCore.Flex, { ...props, direction: direction, justifyContent: justifyContent, alignItems: alignItems, alignSelf: alignSelf, flex: flex, spaceItems: spaceItems, gap: gap, columnGap: columnGap, rowGap: rowGap, order: order, component: component, display: display, "data-semantic-name": defaultSemanticName, "data-semantic-role": role, "data-ai-metadata": JSON.stringify(metadata), "data-purpose": inferredPurpose, "data-layout-type": inferredLayoutType, "data-alignment-context": inferredAlignmentContext, children: children }));
|
|
1019
|
+
};
|
|
1020
|
+
|
|
1021
|
+
/** FlexItem - PatternFly FlexItem wrapper with semantic metadata for AI tooling */
|
|
1022
|
+
const FlexItem = ({ semanticName, semanticRole, aiMetadata, contentType, positioningContext, sizingBehavior, children, flex, align, alignSelf, spacer, order, component, ...props }) => {
|
|
1023
|
+
// Auto-infer semantic properties from PatternFly props
|
|
1024
|
+
const inferredContentType = contentType || (React.Children.toArray(children).some(child => React.isValidElement(child) &&
|
|
1025
|
+
(child.type?.toString().includes('Button') ||
|
|
1026
|
+
child.props?.variant === 'primary' ||
|
|
1027
|
+
child.props?.variant === 'secondary')) ? 'button' :
|
|
1028
|
+
React.Children.toArray(children).some(child => React.isValidElement(child) &&
|
|
1029
|
+
child.type?.toString().includes('Icon')) ? 'icon' :
|
|
1030
|
+
React.Children.toArray(children).some(child => React.isValidElement(child) &&
|
|
1031
|
+
(child.type?.toString().includes('Input') ||
|
|
1032
|
+
child.type?.toString().includes('Select') ||
|
|
1033
|
+
child.type?.toString().includes('Checkbox'))) ? 'form-control' :
|
|
1034
|
+
React.Children.toArray(children).some(child => React.isValidElement(child) &&
|
|
1035
|
+
(child.type?.toString().includes('img') ||
|
|
1036
|
+
child.type?.toString().includes('Image'))) ? 'media' :
|
|
1037
|
+
React.Children.toArray(children).some(child => React.isValidElement(child) &&
|
|
1038
|
+
child.type?.toString().includes('Link')) ? 'navigation' :
|
|
1039
|
+
'text');
|
|
1040
|
+
const inferredPositioningContext = positioningContext || (align?.default === 'alignRight' ? 'end' :
|
|
1041
|
+
align?.default === 'alignLeft' ? 'start' :
|
|
1042
|
+
align?.default === 'alignCenter' ? 'center' :
|
|
1043
|
+
alignSelf?.default === 'alignSelfFlexEnd' ? 'end' :
|
|
1044
|
+
alignSelf?.default === 'alignSelfFlexStart' ? 'start' :
|
|
1045
|
+
alignSelf?.default === 'alignSelfCenter' ? 'center' :
|
|
1046
|
+
alignSelf?.default === 'alignSelfStretch' ? 'stretch' :
|
|
1047
|
+
alignSelf?.default === 'alignSelfBaseline' ? 'baseline' :
|
|
1048
|
+
'auto');
|
|
1049
|
+
const inferredSizingBehavior = sizingBehavior || (flex?.default === 'flex_1' ? 'flexible' :
|
|
1050
|
+
flex?.default === 'flex_2' ? 'grow' :
|
|
1051
|
+
flex?.default === 'flex_3' ? 'grow' :
|
|
1052
|
+
flex?.default === 'flexNone' ? 'fixed' :
|
|
1053
|
+
flex?.default === 'flexDefault' ? 'auto' :
|
|
1054
|
+
flex?.default === 'flex_4' ? 'auto' :
|
|
1055
|
+
'auto');
|
|
1056
|
+
// Generate semantic role and AI metadata
|
|
1057
|
+
const role = semanticRole || `flex-item-${inferredContentType}-${inferredSizingBehavior}`;
|
|
1058
|
+
const metadata = aiMetadata || {
|
|
1059
|
+
description: `${inferredContentType} flex item with ${inferredSizingBehavior} sizing`,
|
|
1060
|
+
category: 'layout',
|
|
1061
|
+
complexity: 'simple',
|
|
1062
|
+
usage: [`${inferredContentType}-item`, `${inferredSizingBehavior}-sizing`, 'flex-layout'],
|
|
1063
|
+
positioning: inferredPositioningContext,
|
|
1064
|
+
sizing: inferredSizingBehavior,
|
|
1065
|
+
spacing: spacer?.default || 'none'
|
|
1066
|
+
};
|
|
1067
|
+
// Default semantic name if not provided
|
|
1068
|
+
const defaultSemanticName = semanticName || 'Flex Item';
|
|
1069
|
+
return (jsxRuntime.jsx(reactCore.FlexItem, { ...props, flex: flex, align: align, alignSelf: alignSelf, spacer: spacer, order: order, component: component, "data-semantic-name": defaultSemanticName, "data-semantic-role": role, "data-ai-metadata": JSON.stringify(metadata), "data-content-type": inferredContentType, "data-positioning-context": inferredPositioningContext, "data-sizing-behavior": inferredSizingBehavior, children: children }));
|
|
1070
|
+
};
|
|
1071
|
+
|
|
1072
|
+
/** Modal - PatternFly Modal wrapper with semantic metadata for AI tooling */
|
|
1073
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1074
|
+
const Modal = React.forwardRef(({ semanticName, semanticRole, aiMetadata: _aiMetadata, purpose, interactionType, triggeredBy, children, variant, isOpen, ...props }, ref) => {
|
|
1075
|
+
// Register as visual parent in semantic context
|
|
1076
|
+
const { addContext, removeContext } = useSemanticContext();
|
|
1077
|
+
React.useEffect(() => {
|
|
1078
|
+
addContext('Modal', undefined, true); // true = qualified visual parent
|
|
1079
|
+
return () => removeContext();
|
|
1080
|
+
}, [addContext, removeContext]);
|
|
1081
|
+
// Get hierarchy from context
|
|
1082
|
+
let hierarchy;
|
|
1083
|
+
try {
|
|
1084
|
+
const semanticContext = useSemanticContext();
|
|
1085
|
+
hierarchy = semanticContext.getHierarchy();
|
|
1086
|
+
}
|
|
1087
|
+
catch {
|
|
1088
|
+
hierarchy = { fullPath: '', qualifiedParents: [], wrappers: [], immediateParent: '', immediateWrapper: '', depth: 0 };
|
|
1089
|
+
}
|
|
1090
|
+
// Auto-infer semantic properties from PatternFly props
|
|
1091
|
+
const inferredPurpose = purpose || inferModalPurpose({ variant });
|
|
1092
|
+
const inferredInteractionType = interactionType || inferModalInteractionType(isOpen);
|
|
1093
|
+
// Auto-infer triggeredBy from current hierarchy context
|
|
1094
|
+
// Extract the semantic name of the last component (usually the triggering button)
|
|
1095
|
+
const inferredTriggeredBy = triggeredBy || (hierarchy.fullPath ?
|
|
1096
|
+
hierarchy.fullPath.split(' > ').pop() || 'unknown' : 'unknown');
|
|
1097
|
+
// Generate semantic role
|
|
1098
|
+
const role = semanticRole || `modal-${inferredPurpose}-${inferredInteractionType}`;
|
|
1099
|
+
// Default semantic name if not provided
|
|
1100
|
+
const componentName = semanticName || 'Modal';
|
|
1101
|
+
return (jsxRuntime.jsx(reactCore.Modal, { ...props, ref: ref, variant: variant, isOpen: isOpen, "data-semantic-name": componentName, "data-semantic-path": hierarchy.fullPath ? `${hierarchy.fullPath} > ${componentName}` : componentName, "data-parent": hierarchy.immediateParent || 'none', "data-wrapper": hierarchy.immediateWrapper || 'none', "data-num-parents": hierarchy.depth, "data-triggered-by": inferredTriggeredBy, "data-semantic-role": role, "data-purpose": inferredPurpose, "data-interaction-type": inferredInteractionType, children: children }));
|
|
1102
|
+
});
|
|
1103
|
+
Modal.displayName = 'Modal';
|
|
1104
|
+
|
|
1105
|
+
/** Drawer - PatternFly Drawer wrapper with semantic metadata for AI tooling */
|
|
1106
|
+
const Drawer = ({ semanticName, semanticRole, purpose, children, isExpanded, ...props }) => {
|
|
1107
|
+
// Register as visual parent in semantic context
|
|
1108
|
+
const { addContext, removeContext } = useSemanticContext();
|
|
1109
|
+
React.useEffect(() => {
|
|
1110
|
+
addContext('Drawer', undefined, true); // true = qualified visual parent
|
|
1111
|
+
return () => removeContext();
|
|
1112
|
+
}, [addContext, removeContext]);
|
|
1113
|
+
// Get hierarchy from context
|
|
1114
|
+
let hierarchy;
|
|
1115
|
+
try {
|
|
1116
|
+
const semanticContext = useSemanticContext();
|
|
1117
|
+
hierarchy = semanticContext.getHierarchy();
|
|
1118
|
+
}
|
|
1119
|
+
catch {
|
|
1120
|
+
hierarchy = { fullPath: '', qualifiedParents: [], wrappers: [], immediateParent: '', immediateWrapper: '', depth: 0 };
|
|
1121
|
+
}
|
|
1122
|
+
// Auto-infer purpose if not provided
|
|
1123
|
+
const inferredPurpose = purpose || 'details';
|
|
1124
|
+
// Generate semantic role
|
|
1125
|
+
const role = semanticRole || `drawer-${inferredPurpose}`;
|
|
1126
|
+
// Default semantic name if not provided
|
|
1127
|
+
const componentName = semanticName || 'Drawer';
|
|
1128
|
+
return (jsxRuntime.jsx(reactCore.Drawer, { ...props, isExpanded: isExpanded, "data-semantic-name": componentName, "data-semantic-path": hierarchy.fullPath ? `${hierarchy.fullPath} > ${componentName}` : componentName, "data-parent": hierarchy.immediateParent || 'none', "data-wrapper": hierarchy.immediateWrapper || 'none', "data-num-parents": hierarchy.depth, "data-semantic-role": role, "data-purpose": inferredPurpose, "data-is-expanded": isExpanded, children: children }));
|
|
1129
|
+
};
|
|
1130
|
+
|
|
1131
|
+
const MenuToggle = ({ semanticName, semanticRole, aiMetadata, target, children, ...props }) => {
|
|
1132
|
+
// Get hierarchy from context (optional)
|
|
1133
|
+
let hierarchy;
|
|
1134
|
+
let semanticContext;
|
|
1135
|
+
try {
|
|
1136
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
1137
|
+
semanticContext = useSemanticContext();
|
|
1138
|
+
}
|
|
1139
|
+
catch {
|
|
1140
|
+
semanticContext = null;
|
|
1141
|
+
}
|
|
1142
|
+
const { addContext, removeContext, getHierarchy } = semanticContext || {
|
|
1143
|
+
addContext: () => { },
|
|
1144
|
+
removeContext: () => { },
|
|
1145
|
+
getHierarchy: () => ({ fullPath: '', qualifiedParents: [], wrappers: [], immediateParent: '', immediateWrapper: '', depth: 0 })
|
|
1146
|
+
};
|
|
1147
|
+
// Add "menu" context when this component mounts/renders
|
|
1148
|
+
React.useEffect(() => {
|
|
1149
|
+
addContext('Menu'); // Auto-detected as non-qualified (wrapper)
|
|
1150
|
+
return () => removeContext();
|
|
1151
|
+
}, [addContext, removeContext]);
|
|
1152
|
+
hierarchy = getHierarchy();
|
|
1153
|
+
const componentName = semanticName || 'Toggle';
|
|
1154
|
+
const metadata = aiMetadata || {
|
|
1155
|
+
hierarchy,
|
|
1156
|
+
action: {
|
|
1157
|
+
type: 'toggle',
|
|
1158
|
+
target: target || 'menu'
|
|
1159
|
+
}
|
|
1160
|
+
};
|
|
1161
|
+
return (jsxRuntime.jsx(reactCore.MenuToggle, { ...props, "data-semantic-name": componentName, "data-semantic-path": hierarchy.fullPath ? `${hierarchy.fullPath} > ${componentName}` : componentName, "data-parent": hierarchy.immediateParent || 'none', "data-wrapper": hierarchy.immediateWrapper || 'none', "data-num-parents": hierarchy.depth, "data-semantic-role": semanticRole || 'menu-trigger', "data-ai-metadata": JSON.stringify(metadata), "data-target": target || 'menu', children: children }));
|
|
1162
|
+
};
|
|
1163
|
+
|
|
1164
|
+
const DropdownItem = ({ semanticName, semanticRole, aiMetadata, target, children, ...props }) => {
|
|
1165
|
+
// Get hierarchy from context (optional)
|
|
1166
|
+
let hierarchy;
|
|
1167
|
+
try {
|
|
1168
|
+
const semanticContext = useSemanticContext();
|
|
1169
|
+
hierarchy = semanticContext.getHierarchy();
|
|
1170
|
+
}
|
|
1171
|
+
catch {
|
|
1172
|
+
hierarchy = { fullPath: '', qualifiedParents: [], wrappers: [], immediateParent: '', immediateWrapper: '', depth: 0 };
|
|
1173
|
+
}
|
|
1174
|
+
const componentName = semanticName || 'Action';
|
|
1175
|
+
const metadata = aiMetadata || {
|
|
1176
|
+
hierarchy,
|
|
1177
|
+
action: {
|
|
1178
|
+
type: 'menu-action',
|
|
1179
|
+
target: target || 'default'
|
|
1180
|
+
}
|
|
1181
|
+
};
|
|
1182
|
+
return (jsxRuntime.jsx(reactCore.DropdownItem, { ...props, "data-semantic-name": componentName, "data-semantic-path": hierarchy.fullPath ? `${hierarchy.fullPath} > ${componentName}` : componentName, "data-parent": hierarchy.immediateParent || 'none', "data-wrapper": hierarchy.immediateWrapper || 'none', "data-num-parents": hierarchy.depth, "data-semantic-role": semanticRole || 'menu-item', "data-ai-metadata": JSON.stringify(metadata), "data-target": target || 'default', children: children }));
|
|
1183
|
+
};
|
|
1184
|
+
|
|
1185
|
+
/**
|
|
1186
|
+
* Utility functions for managing component metadata
|
|
1187
|
+
*/
|
|
1188
|
+
/**
|
|
1189
|
+
* Generates default metadata for a component based on its type and props
|
|
1190
|
+
*/
|
|
1191
|
+
const generateComponentMetadata = (componentName, props = {}) => {
|
|
1192
|
+
const baseMetadata = {
|
|
1193
|
+
name: componentName,
|
|
1194
|
+
description: `Semantic wrapper for ${componentName}`,
|
|
1195
|
+
category: 'data-display',
|
|
1196
|
+
accessibility: ['keyboard-navigable'],
|
|
1197
|
+
usage: ['user-interface'],
|
|
1198
|
+
props: props
|
|
1199
|
+
};
|
|
1200
|
+
// Customize based on component type
|
|
1201
|
+
switch (componentName.toLowerCase()) {
|
|
1202
|
+
case 'button':
|
|
1203
|
+
return {
|
|
1204
|
+
...baseMetadata,
|
|
1205
|
+
category: 'forms',
|
|
1206
|
+
description: 'Interactive button with semantic meaning',
|
|
1207
|
+
usage: ['user-interaction', 'form-submission', 'navigation']
|
|
1208
|
+
};
|
|
1209
|
+
case 'card':
|
|
1210
|
+
return {
|
|
1211
|
+
...baseMetadata,
|
|
1212
|
+
category: 'data-display',
|
|
1213
|
+
description: 'Content container with semantic purpose',
|
|
1214
|
+
usage: ['content-organization', 'data-presentation']
|
|
1215
|
+
};
|
|
1216
|
+
case 'modal':
|
|
1217
|
+
return {
|
|
1218
|
+
...baseMetadata,
|
|
1219
|
+
category: 'overlay',
|
|
1220
|
+
description: 'Overlay dialog with semantic purpose',
|
|
1221
|
+
accessibility: ['keyboard-navigable', 'focus-management', 'screen-reader-friendly'],
|
|
1222
|
+
usage: ['user-interaction', 'workflow-step', 'confirmation']
|
|
1223
|
+
};
|
|
1224
|
+
default:
|
|
1225
|
+
return baseMetadata;
|
|
1226
|
+
}
|
|
1227
|
+
};
|
|
1228
|
+
/**
|
|
1229
|
+
* Validates component metadata
|
|
1230
|
+
*/
|
|
1231
|
+
const validateMetadata = (metadata) => {
|
|
1232
|
+
return !!(metadata.name &&
|
|
1233
|
+
metadata.description &&
|
|
1234
|
+
metadata.category &&
|
|
1235
|
+
Array.isArray(metadata.accessibility) &&
|
|
1236
|
+
Array.isArray(metadata.usage));
|
|
1237
|
+
};
|
|
1238
|
+
/**
|
|
1239
|
+
* Merges user-provided metadata with defaults
|
|
1240
|
+
*/
|
|
1241
|
+
const mergeMetadata = (userMetadata, defaultMetadata) => {
|
|
1242
|
+
return {
|
|
1243
|
+
...defaultMetadata,
|
|
1244
|
+
...userMetadata,
|
|
1245
|
+
accessibility: [...defaultMetadata.accessibility, ...(userMetadata.accessibility || [])],
|
|
1246
|
+
usage: [...defaultMetadata.usage, ...(userMetadata.usage || [])]
|
|
1247
|
+
};
|
|
1248
|
+
};
|
|
1249
|
+
|
|
1250
|
+
/**
|
|
1251
|
+
* Accessibility utility functions
|
|
1252
|
+
*/
|
|
1253
|
+
/**
|
|
1254
|
+
* Generates ARIA attributes based on component context
|
|
1255
|
+
*/
|
|
1256
|
+
const generateAriaAttributes = (componentType) => {
|
|
1257
|
+
const baseAttributes = {};
|
|
1258
|
+
switch (componentType.toLowerCase()) {
|
|
1259
|
+
case 'button':
|
|
1260
|
+
return {
|
|
1261
|
+
...baseAttributes,
|
|
1262
|
+
role: 'button',
|
|
1263
|
+
tabIndex: '0'
|
|
1264
|
+
};
|
|
1265
|
+
case 'card':
|
|
1266
|
+
return {
|
|
1267
|
+
...baseAttributes,
|
|
1268
|
+
role: 'region',
|
|
1269
|
+
tabIndex: '0'
|
|
1270
|
+
};
|
|
1271
|
+
case 'modal':
|
|
1272
|
+
return {
|
|
1273
|
+
...baseAttributes,
|
|
1274
|
+
role: 'dialog',
|
|
1275
|
+
'aria-modal': 'true',
|
|
1276
|
+
tabIndex: '-1'
|
|
1277
|
+
};
|
|
1278
|
+
default:
|
|
1279
|
+
return baseAttributes;
|
|
1280
|
+
}
|
|
1281
|
+
};
|
|
1282
|
+
/**
|
|
1283
|
+
* Validates accessibility requirements
|
|
1284
|
+
*/
|
|
1285
|
+
const validateAccessibility = (componentType, props) => {
|
|
1286
|
+
const issues = [];
|
|
1287
|
+
// Check for required ARIA attributes
|
|
1288
|
+
if (componentType === 'button' && !props['aria-label'] && !props.children) {
|
|
1289
|
+
issues.push('Button should have aria-label or visible text content');
|
|
1290
|
+
}
|
|
1291
|
+
if (componentType === 'modal' && !props['aria-labelledby'] && !props.title) {
|
|
1292
|
+
issues.push('Modal should have aria-labelledby or title');
|
|
1293
|
+
}
|
|
1294
|
+
return issues;
|
|
1295
|
+
};
|
|
1296
|
+
/**
|
|
1297
|
+
* Generates keyboard shortcuts metadata
|
|
1298
|
+
*/
|
|
1299
|
+
const generateKeyboardShortcuts = (componentType, context = {}) => {
|
|
1300
|
+
const shortcuts = [];
|
|
1301
|
+
switch (componentType.toLowerCase()) {
|
|
1302
|
+
case 'button':
|
|
1303
|
+
shortcuts.push('Enter', 'Space');
|
|
1304
|
+
if (context.action === 'close') {
|
|
1305
|
+
shortcuts.push('Escape');
|
|
1306
|
+
}
|
|
1307
|
+
break;
|
|
1308
|
+
case 'modal':
|
|
1309
|
+
shortcuts.push('Escape', 'Tab', 'Shift+Tab');
|
|
1310
|
+
break;
|
|
1311
|
+
case 'card':
|
|
1312
|
+
if (context.interactive) {
|
|
1313
|
+
shortcuts.push('Enter', 'Space');
|
|
1314
|
+
}
|
|
1315
|
+
break;
|
|
1316
|
+
}
|
|
1317
|
+
return shortcuts;
|
|
1318
|
+
};
|
|
1319
|
+
|
|
1320
|
+
/**
|
|
1321
|
+
* Hook for managing semantic metadata for components
|
|
1322
|
+
*/
|
|
1323
|
+
const useSemanticMetadata = (componentName, userMetadata, props = {}) => {
|
|
1324
|
+
const [metadata, setMetadata] = React.useState(() => {
|
|
1325
|
+
const defaultMetadata = generateComponentMetadata(componentName, props);
|
|
1326
|
+
return userMetadata ? mergeMetadata(userMetadata, defaultMetadata) : defaultMetadata;
|
|
1327
|
+
});
|
|
1328
|
+
React.useEffect(() => {
|
|
1329
|
+
const defaultMetadata = generateComponentMetadata(componentName, props);
|
|
1330
|
+
const mergedMetadata = userMetadata ? mergeMetadata(userMetadata, defaultMetadata) : defaultMetadata;
|
|
1331
|
+
setMetadata(mergedMetadata);
|
|
1332
|
+
}, [componentName, userMetadata, props]);
|
|
1333
|
+
const updateMetadata = (updates) => {
|
|
1334
|
+
setMetadata(prev => ({ ...prev, ...updates }));
|
|
1335
|
+
};
|
|
1336
|
+
return {
|
|
1337
|
+
metadata,
|
|
1338
|
+
updateMetadata
|
|
1339
|
+
};
|
|
1340
|
+
};
|
|
1341
|
+
|
|
1342
|
+
/**
|
|
1343
|
+
* Hook for managing accessibility features
|
|
1344
|
+
*/
|
|
1345
|
+
const useAccessibility = (componentType, props = {}, context = {}) => {
|
|
1346
|
+
const ariaAttributes = React.useMemo(() => generateAriaAttributes(componentType), [componentType]);
|
|
1347
|
+
const keyboardShortcuts = React.useMemo(() => generateKeyboardShortcuts(componentType, context), [componentType, context]);
|
|
1348
|
+
const accessibilityIssues = React.useMemo(() => validateAccessibility(componentType, props), [componentType, props]);
|
|
1349
|
+
const enhancedProps = React.useMemo(() => ({
|
|
1350
|
+
...props,
|
|
1351
|
+
...ariaAttributes,
|
|
1352
|
+
'data-keyboard-shortcuts': keyboardShortcuts.join(','),
|
|
1353
|
+
'data-accessibility-issues': accessibilityIssues.join(',')
|
|
1354
|
+
}), [props, ariaAttributes, keyboardShortcuts, accessibilityIssues]);
|
|
1355
|
+
return {
|
|
1356
|
+
ariaAttributes,
|
|
1357
|
+
keyboardShortcuts,
|
|
1358
|
+
accessibilityIssues,
|
|
1359
|
+
enhancedProps
|
|
1360
|
+
};
|
|
1361
|
+
};
|
|
1362
|
+
|
|
1363
|
+
exports.Button = Button;
|
|
1364
|
+
exports.Card = Card;
|
|
1365
|
+
exports.Checkbox = Checkbox;
|
|
1366
|
+
exports.Drawer = Drawer;
|
|
1367
|
+
exports.DropdownItem = DropdownItem;
|
|
1368
|
+
exports.Flex = Flex;
|
|
1369
|
+
exports.FlexItem = FlexItem;
|
|
1370
|
+
exports.Form = Form;
|
|
1371
|
+
exports.Link = Link;
|
|
1372
|
+
exports.MenuToggle = MenuToggle;
|
|
1373
|
+
exports.Modal = Modal;
|
|
1374
|
+
exports.Radio = Radio;
|
|
1375
|
+
exports.Select = Select;
|
|
1376
|
+
exports.SemanticProvider = SemanticProvider;
|
|
1377
|
+
exports.StarIcon = StarIcon;
|
|
1378
|
+
exports.StatusBadge = StatusBadge;
|
|
1379
|
+
exports.Switch = Switch;
|
|
1380
|
+
exports.Tbody = Tbody;
|
|
1381
|
+
exports.Td = Td;
|
|
1382
|
+
exports.TextArea = TextArea;
|
|
1383
|
+
exports.TextInput = TextInput;
|
|
1384
|
+
exports.Th = Th;
|
|
1385
|
+
exports.Thead = Thead;
|
|
1386
|
+
exports.Tr = Tr;
|
|
1387
|
+
exports.generateAriaAttributes = generateAriaAttributes;
|
|
1388
|
+
exports.generateComponentMetadata = generateComponentMetadata;
|
|
1389
|
+
exports.generateKeyboardShortcuts = generateKeyboardShortcuts;
|
|
1390
|
+
exports.generateMetadataFromProps = generateMetadataFromProps;
|
|
1391
|
+
exports.inferAccessibilityFeatures = inferAccessibilityFeatures;
|
|
1392
|
+
exports.inferAlertSeverity = inferAlertSeverity;
|
|
1393
|
+
exports.inferButtonAction = inferButtonAction;
|
|
1394
|
+
exports.inferCardContentType = inferCardContentType;
|
|
1395
|
+
exports.inferCardInteractiveState = inferCardInteractiveState;
|
|
1396
|
+
exports.inferCardPurpose = inferCardPurpose;
|
|
1397
|
+
exports.inferCategory = inferCategory;
|
|
1398
|
+
exports.inferCheckboxPurpose = inferCheckboxPurpose;
|
|
1399
|
+
exports.inferContext = inferContext;
|
|
1400
|
+
exports.inferFormContext = inferFormContext;
|
|
1401
|
+
exports.inferInputPurpose = inferInputPurpose;
|
|
1402
|
+
exports.inferLinkPurpose = inferLinkPurpose;
|
|
1403
|
+
exports.inferModalInteractionType = inferModalInteractionType;
|
|
1404
|
+
exports.inferModalPurpose = inferModalPurpose;
|
|
1405
|
+
exports.inferRadioGroupContext = inferRadioGroupContext;
|
|
1406
|
+
exports.inferRadioPurpose = inferRadioPurpose;
|
|
1407
|
+
exports.inferSelectPurpose = inferSelectPurpose;
|
|
1408
|
+
exports.inferSelectSelectionType = inferSelectSelectionType;
|
|
1409
|
+
exports.inferSettingsContext = inferSettingsContext;
|
|
1410
|
+
exports.inferStarIconPurpose = inferStarIconPurpose;
|
|
1411
|
+
exports.inferStatusBadgePurpose = inferStatusBadgePurpose;
|
|
1412
|
+
exports.inferStatusBadgeType = inferStatusBadgeType;
|
|
1413
|
+
exports.inferSwitchPurpose = inferSwitchPurpose;
|
|
1414
|
+
exports.inferSwitchToggleTarget = inferSwitchToggleTarget;
|
|
1415
|
+
exports.inferTextAreaContentType = inferTextAreaContentType;
|
|
1416
|
+
exports.inferTextAreaPurpose = inferTextAreaPurpose;
|
|
1417
|
+
exports.inferUsagePatterns = inferUsagePatterns;
|
|
1418
|
+
exports.inferValidationContext = inferValidationContext;
|
|
1419
|
+
exports.isVisualParent = isVisualParent;
|
|
1420
|
+
exports.mergeMetadata = mergeMetadata;
|
|
1421
|
+
exports.useAccessibility = useAccessibility;
|
|
1422
|
+
exports.useSemanticContext = useSemanticContext;
|
|
1423
|
+
exports.useSemanticMetadata = useSemanticMetadata;
|
|
1424
|
+
exports.validateAccessibility = validateAccessibility;
|
|
1425
|
+
exports.validateMetadata = validateMetadata;
|
|
1426
|
+
//# sourceMappingURL=index.js.map
|