@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.
Files changed (99) hide show
  1. package/README.md +615 -0
  2. package/codemod/ALL_COMPONENTS_REFERENCE.md +815 -0
  3. package/codemod/ATTRIBUTE_DECISION_LOGIC.md +320 -0
  4. package/codemod/README.md +400 -0
  5. package/codemod/add-semantic-attributes.sh +69 -0
  6. package/codemod/component-attributes-reference.json +129 -0
  7. package/codemod/example-after.tsx +51 -0
  8. package/codemod/example-before.tsx +19 -0
  9. package/codemod/static-inference.js +5015 -0
  10. package/codemod/transform.js +1108 -0
  11. package/dist/components/advanced/index.d.ts +2 -0
  12. package/dist/components/advanced/index.d.ts.map +1 -0
  13. package/dist/components/core/Button.d.ts +14 -0
  14. package/dist/components/core/Button.d.ts.map +1 -0
  15. package/dist/components/core/Link.d.ts +15 -0
  16. package/dist/components/core/Link.d.ts.map +1 -0
  17. package/dist/components/core/StarIcon.d.ts +15 -0
  18. package/dist/components/core/StarIcon.d.ts.map +1 -0
  19. package/dist/components/core/index.d.ts +4 -0
  20. package/dist/components/core/index.d.ts.map +1 -0
  21. package/dist/components/data-display/Card.d.ts +14 -0
  22. package/dist/components/data-display/Card.d.ts.map +1 -0
  23. package/dist/components/data-display/StatusBadge.d.ts +13 -0
  24. package/dist/components/data-display/StatusBadge.d.ts.map +1 -0
  25. package/dist/components/data-display/Tbody.d.ts +12 -0
  26. package/dist/components/data-display/Tbody.d.ts.map +1 -0
  27. package/dist/components/data-display/Td.d.ts +14 -0
  28. package/dist/components/data-display/Td.d.ts.map +1 -0
  29. package/dist/components/data-display/Th.d.ts +14 -0
  30. package/dist/components/data-display/Th.d.ts.map +1 -0
  31. package/dist/components/data-display/Thead.d.ts +12 -0
  32. package/dist/components/data-display/Thead.d.ts.map +1 -0
  33. package/dist/components/data-display/Tr.d.ts +16 -0
  34. package/dist/components/data-display/Tr.d.ts.map +1 -0
  35. package/dist/components/data-display/index.d.ts +8 -0
  36. package/dist/components/data-display/index.d.ts.map +1 -0
  37. package/dist/components/feedback/index.d.ts +2 -0
  38. package/dist/components/feedback/index.d.ts.map +1 -0
  39. package/dist/components/forms/Checkbox.d.ts +16 -0
  40. package/dist/components/forms/Checkbox.d.ts.map +1 -0
  41. package/dist/components/forms/Form.d.ts +12 -0
  42. package/dist/components/forms/Form.d.ts.map +1 -0
  43. package/dist/components/forms/Radio.d.ts +32 -0
  44. package/dist/components/forms/Radio.d.ts.map +1 -0
  45. package/dist/components/forms/Select.d.ts +33 -0
  46. package/dist/components/forms/Select.d.ts.map +1 -0
  47. package/dist/components/forms/Switch.d.ts +31 -0
  48. package/dist/components/forms/Switch.d.ts.map +1 -0
  49. package/dist/components/forms/TextArea.d.ts +29 -0
  50. package/dist/components/forms/TextArea.d.ts.map +1 -0
  51. package/dist/components/forms/TextInput.d.ts +29 -0
  52. package/dist/components/forms/TextInput.d.ts.map +1 -0
  53. package/dist/components/forms/index.d.ts +8 -0
  54. package/dist/components/forms/index.d.ts.map +1 -0
  55. package/dist/components/index.d.ts +9 -0
  56. package/dist/components/index.d.ts.map +1 -0
  57. package/dist/components/layout/Flex.d.ts +16 -0
  58. package/dist/components/layout/Flex.d.ts.map +1 -0
  59. package/dist/components/layout/FlexItem.d.ts +16 -0
  60. package/dist/components/layout/FlexItem.d.ts.map +1 -0
  61. package/dist/components/layout/index.d.ts +3 -0
  62. package/dist/components/layout/index.d.ts.map +1 -0
  63. package/dist/components/navigation/DropdownItem.d.ts +8 -0
  64. package/dist/components/navigation/DropdownItem.d.ts.map +1 -0
  65. package/dist/components/navigation/MenuToggle.d.ts +8 -0
  66. package/dist/components/navigation/MenuToggle.d.ts.map +1 -0
  67. package/dist/components/navigation/index.d.ts +3 -0
  68. package/dist/components/navigation/index.d.ts.map +1 -0
  69. package/dist/components/overlay/Drawer.d.ts +12 -0
  70. package/dist/components/overlay/Drawer.d.ts.map +1 -0
  71. package/dist/components/overlay/Modal.d.ts +16 -0
  72. package/dist/components/overlay/Modal.d.ts.map +1 -0
  73. package/dist/components/overlay/index.d.ts +3 -0
  74. package/dist/components/overlay/index.d.ts.map +1 -0
  75. package/dist/context/SemanticContext.d.ts +28 -0
  76. package/dist/context/SemanticContext.d.ts.map +1 -0
  77. package/dist/hooks/index.d.ts +3 -0
  78. package/dist/hooks/index.d.ts.map +1 -0
  79. package/dist/hooks/useAccessibility.d.ts +13 -0
  80. package/dist/hooks/useAccessibility.d.ts.map +1 -0
  81. package/dist/hooks/useSemanticMetadata.d.ts +9 -0
  82. package/dist/hooks/useSemanticMetadata.d.ts.map +1 -0
  83. package/dist/index.d.ts +574 -0
  84. package/dist/index.d.ts.map +1 -0
  85. package/dist/index.esm.js +1362 -0
  86. package/dist/index.esm.js.map +1 -0
  87. package/dist/index.js +1426 -0
  88. package/dist/index.js.map +1 -0
  89. package/dist/types/index.d.ts +47 -0
  90. package/dist/types/index.d.ts.map +1 -0
  91. package/dist/utils/accessibility.d.ts +16 -0
  92. package/dist/utils/accessibility.d.ts.map +1 -0
  93. package/dist/utils/index.d.ts +4 -0
  94. package/dist/utils/index.d.ts.map +1 -0
  95. package/dist/utils/inference.d.ts +136 -0
  96. package/dist/utils/inference.d.ts.map +1 -0
  97. package/dist/utils/metadata.d.ts +17 -0
  98. package/dist/utils/metadata.d.ts.map +1 -0
  99. 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