@fgv/ts-res-ui-components 5.0.0-21 → 5.0.0-23

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 (192) hide show
  1. package/README.md +401 -155
  2. package/config/jest.setup.js +10 -0
  3. package/dist/ts-res-ui-components.d.ts +1657 -76
  4. package/lib/components/common/QualifierContextControl.js +4 -1
  5. package/lib/components/common/ResourceTreeView.js +4 -1
  6. package/lib/components/forms/GenericQualifierTypeEditForm.d.ts +26 -0
  7. package/lib/components/forms/GenericQualifierTypeEditForm.js +166 -0
  8. package/lib/components/forms/QualifierEditForm.d.ts +1 -1
  9. package/lib/components/forms/index.d.ts +2 -0
  10. package/lib/components/forms/index.js +1 -0
  11. package/lib/components/orchestrator/ResourceOrchestrator.d.ts +3 -0
  12. package/lib/components/orchestrator/ResourceOrchestrator.js +118 -51
  13. package/lib/components/pickers/ResourcePicker/ResourcePickerTree.js +32 -10
  14. package/lib/components/pickers/ResourcePicker/index.js +4 -2
  15. package/lib/components/views/CompiledView/index.js +75 -16
  16. package/lib/components/views/ConfigurationView/index.js +94 -35
  17. package/lib/components/views/FilterView/index.js +7 -4
  18. package/lib/components/views/GridView/EditableGridCell.d.ts +76 -0
  19. package/lib/components/views/GridView/EditableGridCell.js +224 -0
  20. package/lib/components/views/GridView/GridSelector.d.ts +43 -0
  21. package/lib/components/views/GridView/GridSelector.js +89 -0
  22. package/lib/components/views/GridView/MultiGridView.d.ts +85 -0
  23. package/lib/components/views/GridView/MultiGridView.js +196 -0
  24. package/lib/components/views/GridView/ResourceGrid.d.ts +38 -0
  25. package/lib/components/views/GridView/ResourceGrid.js +232 -0
  26. package/lib/components/views/GridView/SharedContextControls.d.ts +47 -0
  27. package/lib/components/views/GridView/SharedContextControls.js +95 -0
  28. package/lib/components/views/GridView/cells/BooleanCell.d.ts +44 -0
  29. package/lib/components/views/GridView/cells/BooleanCell.js +49 -0
  30. package/lib/components/views/GridView/cells/DropdownCell.d.ts +58 -0
  31. package/lib/components/views/GridView/cells/DropdownCell.js +182 -0
  32. package/lib/components/views/GridView/cells/StringCell.d.ts +57 -0
  33. package/lib/components/views/GridView/cells/StringCell.js +106 -0
  34. package/lib/components/views/GridView/cells/TriStateCell.d.ts +54 -0
  35. package/lib/components/views/GridView/cells/TriStateCell.js +112 -0
  36. package/lib/components/views/GridView/cells/index.d.ts +15 -0
  37. package/lib/components/views/GridView/cells/index.js +11 -0
  38. package/lib/components/views/GridView/index.d.ts +53 -0
  39. package/lib/components/views/GridView/index.js +212 -0
  40. package/lib/components/views/ImportView/index.js +22 -19
  41. package/lib/components/views/MessagesWindow/index.js +4 -1
  42. package/lib/components/views/ResolutionView/index.js +8 -5
  43. package/lib/contexts/ObservabilityContext.d.ts +85 -0
  44. package/lib/contexts/ObservabilityContext.js +98 -0
  45. package/lib/contexts/index.d.ts +2 -0
  46. package/lib/contexts/index.js +24 -0
  47. package/lib/hooks/useConfigurationState.d.ts +3 -3
  48. package/lib/hooks/useResolutionState.js +850 -246
  49. package/lib/hooks/useResourceData.d.ts +7 -4
  50. package/lib/hooks/useResourceData.js +185 -184
  51. package/lib/index.d.ts +5 -1
  52. package/lib/index.js +8 -1
  53. package/lib/namespaces/GridTools.d.ts +136 -0
  54. package/lib/namespaces/GridTools.js +138 -0
  55. package/lib/namespaces/ObservabilityTools.d.ts +3 -0
  56. package/lib/namespaces/ObservabilityTools.js +23 -0
  57. package/lib/namespaces/ResolutionTools.d.ts +2 -1
  58. package/lib/namespaces/ResolutionTools.js +2 -0
  59. package/lib/namespaces/index.d.ts +2 -0
  60. package/lib/namespaces/index.js +2 -0
  61. package/lib/test/integration/observability.integration.test.d.ts +2 -0
  62. package/lib/test/unit/hooks/useResourceData.test.d.ts +2 -0
  63. package/lib/test/unit/utils/downloadHelper.test.d.ts +2 -0
  64. package/lib/test/unit/workflows/resolutionWorkflows.test.d.ts +2 -0
  65. package/lib/test/unit/workflows/resourceCreation.test.d.ts +2 -0
  66. package/lib/test/unit/workflows/resultPatternExtensions.test.d.ts +2 -0
  67. package/lib/test/unit/workflows/validation.test.d.ts +2 -0
  68. package/lib/types/index.d.ts +387 -20
  69. package/lib/types/index.js +2 -1
  70. package/lib/utils/cellValidation.d.ts +113 -0
  71. package/lib/utils/cellValidation.js +248 -0
  72. package/lib/utils/downloadHelper.d.ts +66 -0
  73. package/lib/utils/downloadHelper.js +195 -0
  74. package/lib/utils/observability/factories.d.ts +29 -0
  75. package/lib/utils/observability/factories.js +58 -0
  76. package/lib/utils/observability/implementations.d.ts +61 -0
  77. package/lib/utils/observability/implementations.js +103 -0
  78. package/lib/utils/observability/index.d.ts +4 -0
  79. package/lib/utils/observability/index.js +26 -0
  80. package/lib/utils/observability/interfaces.d.ts +30 -0
  81. package/lib/utils/observability/interfaces.js +23 -0
  82. package/lib/utils/resolutionEditing.js +2 -1
  83. package/lib/utils/resourceSelector.d.ts +97 -0
  84. package/lib/utils/resourceSelector.js +195 -0
  85. package/lib/utils/resourceSelectors.d.ts +146 -0
  86. package/lib/utils/resourceSelectors.js +233 -0
  87. package/lib/utils/tsResIntegration.d.ts +6 -41
  88. package/lib/utils/tsResIntegration.js +20 -16
  89. package/lib/utils/zipLoader/zipProcessingHelpers.d.ts +3 -2
  90. package/lib/utils/zipLoader/zipProcessingHelpers.js +6 -5
  91. package/lib-commonjs/components/common/QualifierContextControl.js +4 -1
  92. package/lib-commonjs/components/common/ResourceTreeView.js +4 -1
  93. package/lib-commonjs/components/forms/GenericQualifierTypeEditForm.js +171 -0
  94. package/lib-commonjs/components/forms/index.js +3 -1
  95. package/lib-commonjs/components/orchestrator/ResourceOrchestrator.js +118 -51
  96. package/lib-commonjs/components/pickers/ResourcePicker/ResourcePickerTree.js +32 -10
  97. package/lib-commonjs/components/pickers/ResourcePicker/index.js +4 -2
  98. package/lib-commonjs/components/views/CompiledView/index.js +75 -16
  99. package/lib-commonjs/components/views/ConfigurationView/index.js +93 -34
  100. package/lib-commonjs/components/views/FilterView/index.js +7 -4
  101. package/lib-commonjs/components/views/GridView/EditableGridCell.js +232 -0
  102. package/lib-commonjs/components/views/GridView/GridSelector.js +94 -0
  103. package/lib-commonjs/components/views/GridView/MultiGridView.js +201 -0
  104. package/lib-commonjs/components/views/GridView/ResourceGrid.js +237 -0
  105. package/lib-commonjs/components/views/GridView/SharedContextControls.js +100 -0
  106. package/lib-commonjs/components/views/GridView/cells/BooleanCell.js +54 -0
  107. package/lib-commonjs/components/views/GridView/cells/DropdownCell.js +187 -0
  108. package/lib-commonjs/components/views/GridView/cells/StringCell.js +111 -0
  109. package/lib-commonjs/components/views/GridView/cells/TriStateCell.js +117 -0
  110. package/lib-commonjs/components/views/GridView/cells/index.js +18 -0
  111. package/lib-commonjs/components/views/GridView/index.js +217 -0
  112. package/lib-commonjs/components/views/ImportView/index.js +22 -19
  113. package/lib-commonjs/components/views/MessagesWindow/index.js +4 -1
  114. package/lib-commonjs/components/views/ResolutionView/index.js +8 -5
  115. package/lib-commonjs/contexts/ObservabilityContext.js +104 -0
  116. package/lib-commonjs/contexts/index.js +30 -0
  117. package/lib-commonjs/hooks/useResolutionState.js +849 -245
  118. package/lib-commonjs/hooks/useResourceData.js +184 -215
  119. package/lib-commonjs/index.js +15 -1
  120. package/lib-commonjs/namespaces/GridTools.js +161 -0
  121. package/lib-commonjs/namespaces/ObservabilityTools.js +33 -0
  122. package/lib-commonjs/namespaces/ResolutionTools.js +10 -1
  123. package/lib-commonjs/namespaces/index.js +3 -1
  124. package/lib-commonjs/types/index.js +10 -0
  125. package/lib-commonjs/utils/cellValidation.js +253 -0
  126. package/lib-commonjs/utils/downloadHelper.js +198 -0
  127. package/lib-commonjs/utils/observability/factories.js +63 -0
  128. package/lib-commonjs/utils/observability/implementations.js +109 -0
  129. package/lib-commonjs/utils/observability/index.js +36 -0
  130. package/lib-commonjs/utils/observability/interfaces.js +24 -0
  131. package/lib-commonjs/utils/resolutionEditing.js +2 -1
  132. package/lib-commonjs/utils/resourceSelector.js +200 -0
  133. package/lib-commonjs/utils/resourceSelectors.js +242 -0
  134. package/lib-commonjs/utils/tsResIntegration.js +21 -16
  135. package/lib-commonjs/utils/zipLoader/zipProcessingHelpers.js +7 -5
  136. package/package.json +7 -7
  137. package/src/components/common/QualifierContextControl.tsx +0 -338
  138. package/src/components/common/ResolutionContextOptionsControl.tsx +0 -450
  139. package/src/components/common/ResolutionResults/index.tsx +0 -481
  140. package/src/components/common/ResourceListView.tsx +0 -167
  141. package/src/components/common/ResourcePickerOptionsControl.tsx +0 -351
  142. package/src/components/common/ResourceTreeView.tsx +0 -417
  143. package/src/components/common/SourceResourceDetail/index.tsx +0 -493
  144. package/src/components/forms/HierarchyEditor.tsx +0 -285
  145. package/src/components/forms/QualifierEditForm.tsx +0 -487
  146. package/src/components/forms/QualifierTypeEditForm.tsx +0 -458
  147. package/src/components/forms/ResourceTypeEditForm.tsx +0 -437
  148. package/src/components/forms/index.ts +0 -11
  149. package/src/components/orchestrator/ResourceOrchestrator.tsx +0 -444
  150. package/src/components/pickers/ResourcePicker/README.md +0 -570
  151. package/src/components/pickers/ResourcePicker/ResourceItem.tsx +0 -127
  152. package/src/components/pickers/ResourcePicker/ResourcePickerList.tsx +0 -114
  153. package/src/components/pickers/ResourcePicker/ResourcePickerTree.tsx +0 -461
  154. package/src/components/pickers/ResourcePicker/index.tsx +0 -234
  155. package/src/components/pickers/ResourcePicker/types.ts +0 -301
  156. package/src/components/pickers/ResourcePicker/utils/treeNavigation.ts +0 -210
  157. package/src/components/views/CompiledView/index.tsx +0 -1342
  158. package/src/components/views/ConfigurationView/index.tsx +0 -848
  159. package/src/components/views/FilterView/index.tsx +0 -681
  160. package/src/components/views/ImportView/index.tsx +0 -789
  161. package/src/components/views/MessagesWindow/index.tsx +0 -325
  162. package/src/components/views/ResolutionView/EditableJsonView.tsx +0 -386
  163. package/src/components/views/ResolutionView/NewResourceModal.tsx +0 -158
  164. package/src/components/views/ResolutionView/UnifiedChangeControls.tsx +0 -163
  165. package/src/components/views/ResolutionView/index.tsx +0 -751
  166. package/src/components/views/SourceView/index.tsx +0 -291
  167. package/src/hooks/useConfigurationState.ts +0 -436
  168. package/src/hooks/useFilterState.ts +0 -150
  169. package/src/hooks/useResolutionState.ts +0 -893
  170. package/src/hooks/useResourceData.ts +0 -596
  171. package/src/hooks/useViewState.ts +0 -97
  172. package/src/index.ts +0 -68
  173. package/src/namespaces/ConfigurationTools.ts +0 -59
  174. package/src/namespaces/FilterTools.ts +0 -47
  175. package/src/namespaces/ImportTools.ts +0 -42
  176. package/src/namespaces/PickerTools.ts +0 -104
  177. package/src/namespaces/ResolutionTools.ts +0 -68
  178. package/src/namespaces/ResourceTools.ts +0 -106
  179. package/src/namespaces/TsResTools.ts +0 -49
  180. package/src/namespaces/ViewStateTools.ts +0 -91
  181. package/src/namespaces/ZipTools.ts +0 -49
  182. package/src/namespaces/index.ts +0 -49
  183. package/src/types/index.ts +0 -1273
  184. package/src/utils/configurationUtils.ts +0 -339
  185. package/src/utils/fileProcessing.ts +0 -164
  186. package/src/utils/filterResources.ts +0 -356
  187. package/src/utils/resolutionEditing.ts +0 -346
  188. package/src/utils/resolutionUtils.ts +0 -740
  189. package/src/utils/tsResIntegration.ts +0 -475
  190. package/src/utils/zipLoader/index.ts +0 -5
  191. package/src/utils/zipLoader/zipProcessingHelpers.ts +0 -46
  192. package/src/utils/zipLoader/zipUtils.ts +0 -7
@@ -1,450 +0,0 @@
1
- import React, { useState, useCallback } from 'react';
2
- import { CogIcon, ChevronDownIcon, ChevronUpIcon, XMarkIcon } from '@heroicons/react/24/outline';
3
- import { ResolutionContextOptions, QualifierControlOptions } from '../../types';
4
-
5
- /**
6
- * Props for the ResolutionContextOptionsControl component.
7
- * @public
8
- */
9
- export interface ResolutionContextOptionsControlProps {
10
- /** Current context options */
11
- options: ResolutionContextOptions;
12
- /** Callback when options change */
13
- onOptionsChange: (options: ResolutionContextOptions) => void;
14
- /** Available qualifiers for configuration */
15
- availableQualifiers?: string[];
16
- /** How to present the options control (default: 'hidden' for production use) */
17
- presentation?: 'hidden' | 'inline' | 'collapsible' | 'popup' | 'popover';
18
- /** Custom class name */
19
- className?: string;
20
- /** Title for the control section */
21
- title?: string;
22
- /** Editing/creation toggle - when provided, show UI to control it */
23
- allowResourceCreation?: boolean;
24
- /** Callback for editing/creation toggle */
25
- onAllowResourceCreationChange?: (allow: boolean) => void;
26
- /** Pending resources list visibility - when provided, show UI to control it */
27
- showPendingResourcesInList?: boolean;
28
- /** Callback for pending resources list visibility */
29
- onShowPendingResourcesInListChange?: (show: boolean) => void;
30
- }
31
-
32
- /**
33
- * Reusable control for configuring ResolutionView context options.
34
- *
35
- * Provides a clean interface for adjusting context behavior including:
36
- * - Visibility of context controls, current context display, and action buttons
37
- * - Per-qualifier options (visibility, editability, host values)
38
- * - Global defaults and appearance customization
39
- *
40
- * Can be rendered in multiple presentation modes:
41
- * - 'hidden': Not displayed (default for production)
42
- * - 'inline': Always expanded with full controls visible
43
- * - 'collapsible': Expandable/collapsible section
44
- * - 'popover': Small dropdown overlay
45
- * - 'popup': Full modal dialog
46
- *
47
- * @example
48
- * ```tsx
49
- * import { ResolutionContextOptionsControl } from '@fgv/ts-res-ui-components';
50
- *
51
- * function ContextConfiguration() {
52
- * const [contextOptions, setContextOptions] = useState<ResolutionContextOptions>({});
53
- *
54
- * return (
55
- * <ResolutionContextOptionsControl
56
- * options={contextOptions}
57
- * onOptionsChange={setContextOptions}
58
- * availableQualifiers={['language', 'platform', 'env']}
59
- * presentation="collapsible"
60
- * title="Context Configuration"
61
- * />
62
- * );
63
- * }
64
- * ```
65
- *
66
- * @public
67
- */
68
- export const ResolutionContextOptionsControl: React.FC<ResolutionContextOptionsControlProps> = ({
69
- options,
70
- onOptionsChange,
71
- availableQualifiers = [],
72
- presentation = 'hidden',
73
- className = '',
74
- title = 'Context Options',
75
- allowResourceCreation,
76
- onAllowResourceCreationChange,
77
- showPendingResourcesInList,
78
- onShowPendingResourcesInListChange
79
- }) => {
80
- // Early return for hidden presentation
81
- if (presentation === 'hidden') {
82
- return null;
83
- }
84
-
85
- const [isExpanded, setIsExpanded] = useState(presentation === 'inline');
86
- const [showPopover, setShowPopover] = useState(false);
87
-
88
- const handleOptionChange = useCallback(
89
- <K extends keyof ResolutionContextOptions>(key: K, value: ResolutionContextOptions[K]) => {
90
- onOptionsChange({
91
- ...options,
92
- [key]: value
93
- });
94
- },
95
- [options, onOptionsChange]
96
- );
97
-
98
- const handleQualifierOptionChange = useCallback(
99
- (qualifierName: string, optionKey: keyof QualifierControlOptions, value: any) => {
100
- const currentQualifierOptions = options.qualifierOptions || {};
101
- const currentOptions = currentQualifierOptions[qualifierName] || {};
102
-
103
- const updatedQualifierOptions = {
104
- ...currentQualifierOptions,
105
- [qualifierName]: {
106
- ...currentOptions,
107
- [optionKey]: value
108
- }
109
- };
110
-
111
- handleOptionChange('qualifierOptions', updatedQualifierOptions);
112
- },
113
- [options.qualifierOptions, handleOptionChange]
114
- );
115
-
116
- const handleHostManagedValueChange = useCallback(
117
- (qualifierName: string, value: string | undefined) => {
118
- const currentHostValues = options.hostManagedValues || {};
119
- const updatedHostValues = {
120
- ...currentHostValues,
121
- [qualifierName]: value || undefined
122
- };
123
-
124
- // Remove undefined values to keep object clean
125
- if (value === undefined || value === '') {
126
- delete updatedHostValues[qualifierName];
127
- }
128
-
129
- handleOptionChange('hostManagedValues', updatedHostValues);
130
- },
131
- [options.hostManagedValues, handleOptionChange]
132
- );
133
-
134
- const renderControls = () => (
135
- <div className="space-y-4">
136
- {/* Visibility Settings */}
137
- <div className="space-y-3">
138
- <h4 className="text-sm font-medium text-gray-700">Context Panel Visibility</h4>
139
-
140
- <div className="space-y-2">
141
- <label className="flex items-center text-xs">
142
- <input
143
- type="checkbox"
144
- checked={options.showContextControls !== false}
145
- onChange={(e) => handleOptionChange('showContextControls', e.target.checked)}
146
- className="mr-2 rounded"
147
- />
148
- Show Context Controls
149
- </label>
150
- <label className="flex items-center text-xs">
151
- <input
152
- type="checkbox"
153
- checked={options.showCurrentContext !== false}
154
- onChange={(e) => handleOptionChange('showCurrentContext', e.target.checked)}
155
- className="mr-2 rounded"
156
- />
157
- Show Current Context Display
158
- </label>
159
- <label className="flex items-center text-xs">
160
- <input
161
- type="checkbox"
162
- checked={options.showContextActions !== false}
163
- onChange={(e) => handleOptionChange('showContextActions', e.target.checked)}
164
- className="mr-2 rounded"
165
- />
166
- Show Context Action Buttons
167
- </label>
168
- </div>
169
- </div>
170
-
171
- {/* Global Defaults */}
172
- <div className="space-y-3 pt-3 border-t border-gray-200">
173
- <h4 className="text-sm font-medium text-gray-700">Global Defaults</h4>
174
-
175
- <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
176
- <label className="flex items-center text-xs">
177
- <input
178
- type="checkbox"
179
- checked={options.defaultQualifierVisible !== false}
180
- onChange={(e) => handleOptionChange('defaultQualifierVisible', e.target.checked)}
181
- className="mr-2 rounded"
182
- />
183
- Qualifiers Visible by Default
184
- </label>
185
- <label className="flex items-center text-xs">
186
- <input
187
- type="checkbox"
188
- checked={options.defaultQualifierEditable !== false}
189
- onChange={(e) => handleOptionChange('defaultQualifierEditable', e.target.checked)}
190
- className="mr-2 rounded"
191
- />
192
- Qualifiers Editable by Default
193
- </label>
194
- </div>
195
-
196
- <div>
197
- <label className="block text-xs font-medium text-gray-600 mb-1">Panel Title</label>
198
- <input
199
- type="text"
200
- value={options.contextPanelTitle || ''}
201
- onChange={(e) => handleOptionChange('contextPanelTitle', e.target.value || undefined)}
202
- placeholder="Context Configuration"
203
- className="w-full px-2 py-1 text-xs border border-gray-300 rounded focus:outline-none focus:ring-1 focus:ring-blue-500"
204
- />
205
- </div>
206
-
207
- <div>
208
- <label className="block text-xs font-medium text-gray-600 mb-1">Global Placeholder</label>
209
- <input
210
- type="text"
211
- value={typeof options.globalPlaceholder === 'string' ? options.globalPlaceholder : ''}
212
- onChange={(e) => handleOptionChange('globalPlaceholder', e.target.value || undefined)}
213
- placeholder="Enter {qualifierName} value"
214
- className="w-full px-2 py-1 text-xs border border-gray-300 rounded focus:outline-none focus:ring-1 focus:ring-blue-500"
215
- />
216
- <p className="text-xs text-gray-500 mt-1">Use {'{qualifierName}'} for dynamic qualifier names</p>
217
- </div>
218
- </div>
219
-
220
- {/* Editing & Creation (optional, when props provided) */}
221
- {(allowResourceCreation !== undefined || showPendingResourcesInList !== undefined) && (
222
- <div className="space-y-3 pt-3 border-t border-gray-200">
223
- <h4 className="text-sm font-medium text-gray-700">Editing & Creation</h4>
224
- {allowResourceCreation !== undefined && (
225
- <label className="flex items-center text-xs">
226
- <input
227
- type="checkbox"
228
- checked={!!allowResourceCreation}
229
- onChange={(e) => onAllowResourceCreationChange?.(e.target.checked)}
230
- className="mr-2 rounded"
231
- />
232
- Allow Resource Creation
233
- </label>
234
- )}
235
- {showPendingResourcesInList !== undefined && (
236
- <label className="flex items-center text-xs">
237
- <input
238
- type="checkbox"
239
- checked={!!showPendingResourcesInList}
240
- onChange={(e) => onShowPendingResourcesInListChange?.(e.target.checked)}
241
- className="mr-2 rounded"
242
- />
243
- Show Pending Resources In List
244
- </label>
245
- )}
246
- </div>
247
- )}
248
-
249
- {/* Per-Qualifier Configuration */}
250
- {availableQualifiers.length > 0 && (
251
- <div className="space-y-3 pt-3 border-t border-gray-200">
252
- <h4 className="text-sm font-medium text-gray-700">Per-Qualifier Settings</h4>
253
-
254
- <div className="space-y-3">
255
- {availableQualifiers.map((qualifierName) => {
256
- const qualifierOptions = options.qualifierOptions?.[qualifierName] || {};
257
- const hostValue = options.hostManagedValues?.[qualifierName];
258
-
259
- return (
260
- <div key={qualifierName} className="border border-gray-200 rounded p-3">
261
- <h5 className="text-xs font-medium text-gray-800 mb-2">{qualifierName}</h5>
262
-
263
- <div className="grid grid-cols-1 sm:grid-cols-2 gap-2 mb-2">
264
- <label className="flex items-center text-xs">
265
- <input
266
- type="checkbox"
267
- checked={qualifierOptions.visible !== false}
268
- onChange={(e) =>
269
- handleQualifierOptionChange(qualifierName, 'visible', e.target.checked)
270
- }
271
- className="mr-2 rounded"
272
- />
273
- Visible
274
- </label>
275
- <label className="flex items-center text-xs">
276
- <input
277
- type="checkbox"
278
- checked={qualifierOptions.editable !== false}
279
- onChange={(e) =>
280
- handleQualifierOptionChange(qualifierName, 'editable', e.target.checked)
281
- }
282
- className="mr-2 rounded"
283
- />
284
- Editable
285
- </label>
286
- </div>
287
-
288
- <div className="space-y-2">
289
- <div>
290
- <label className="block text-xs font-medium text-gray-600 mb-1">
291
- Custom Placeholder
292
- </label>
293
- <input
294
- type="text"
295
- value={qualifierOptions.placeholder || ''}
296
- onChange={(e) =>
297
- handleQualifierOptionChange(
298
- qualifierName,
299
- 'placeholder',
300
- e.target.value || undefined
301
- )
302
- }
303
- placeholder={`Enter ${qualifierName} value`}
304
- className="w-full px-2 py-1 text-xs border border-gray-300 rounded focus:outline-none focus:ring-1 focus:ring-blue-500"
305
- />
306
- </div>
307
-
308
- <div>
309
- <label className="block text-xs font-medium text-gray-600 mb-1">
310
- Host-Managed Value
311
- </label>
312
- <input
313
- type="text"
314
- value={hostValue || ''}
315
- onChange={(e) => handleHostManagedValueChange(qualifierName, e.target.value)}
316
- placeholder="Leave empty for user control"
317
- className="w-full px-2 py-1 text-xs border border-gray-300 rounded focus:outline-none focus:ring-1 focus:ring-blue-500"
318
- />
319
- <p className="text-xs text-gray-500 mt-1">
320
- When set, overrides user input and makes field readonly
321
- </p>
322
- </div>
323
-
324
- <label className="flex items-center text-xs">
325
- <input
326
- type="checkbox"
327
- checked={qualifierOptions.showHostValue !== false}
328
- onChange={(e) =>
329
- handleQualifierOptionChange(qualifierName, 'showHostValue', e.target.checked)
330
- }
331
- className="mr-2 rounded"
332
- />
333
- Show Host-Managed Indicator
334
- </label>
335
- </div>
336
- </div>
337
- );
338
- })}
339
- </div>
340
- </div>
341
- )}
342
- </div>
343
- );
344
-
345
- if (presentation === 'popover') {
346
- return (
347
- <div className={`relative ${className}`}>
348
- <button
349
- onClick={() => setShowPopover(!showPopover)}
350
- className="flex items-center px-3 py-1.5 text-xs font-medium text-gray-700 bg-white border border-gray-300 rounded hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500"
351
- >
352
- <CogIcon className="w-3 h-3 mr-1" />
353
- {title}
354
- <ChevronDownIcon className="w-3 h-3 ml-1" />
355
- </button>
356
-
357
- {showPopover && (
358
- <>
359
- {/* Backdrop */}
360
- <div className="fixed inset-0 z-10" onClick={() => setShowPopover(false)} />
361
-
362
- {/* Popover */}
363
- <div className="absolute top-full left-0 mt-1 w-96 bg-white border border-gray-200 rounded-lg shadow-lg z-20 p-4 max-h-96 overflow-y-auto">
364
- <div className="flex items-center justify-between mb-3">
365
- <h3 className="text-sm font-medium text-gray-900">{title}</h3>
366
- <button
367
- onClick={() => setShowPopover(false)}
368
- className="p-1 text-gray-400 hover:text-gray-600"
369
- >
370
- <XMarkIcon className="w-4 h-4" />
371
- </button>
372
- </div>
373
- {renderControls()}
374
- </div>
375
- </>
376
- )}
377
- </div>
378
- );
379
- }
380
-
381
- if (presentation === 'collapsible') {
382
- return (
383
- <div className={`border border-gray-200 rounded-lg ${className}`}>
384
- <button
385
- onClick={() => setIsExpanded(!isExpanded)}
386
- className="w-full flex items-center justify-between px-4 py-2 text-sm font-medium text-gray-700 bg-gray-50 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 rounded-t-lg"
387
- >
388
- <span className="flex items-center">
389
- <CogIcon className="w-4 h-4 mr-2" />
390
- {title}
391
- </span>
392
- {isExpanded ? <ChevronUpIcon className="w-4 h-4" /> : <ChevronDownIcon className="w-4 h-4" />}
393
- </button>
394
-
395
- {isExpanded && <div className="p-4 border-t border-gray-200">{renderControls()}</div>}
396
- </div>
397
- );
398
- }
399
-
400
- if (presentation === 'popup') {
401
- return (
402
- <div className={`relative ${className}`}>
403
- <button
404
- onClick={() => setShowPopover(!showPopover)}
405
- className="flex items-center px-3 py-1.5 text-xs font-medium text-gray-700 bg-white border border-gray-300 rounded hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500"
406
- >
407
- <CogIcon className="w-3 h-3 mr-1" />
408
- {title}
409
- <ChevronDownIcon className="w-3 h-3 ml-1" />
410
- </button>
411
-
412
- {showPopover && (
413
- <>
414
- {/* Backdrop */}
415
- <div className="fixed inset-0 z-40" onClick={() => setShowPopover(false)} />
416
-
417
- {/* Modal Popup */}
418
- <div className="fixed inset-0 z-50 flex items-center justify-center p-4">
419
- <div className="bg-white border border-gray-200 rounded-lg shadow-xl max-w-2xl w-full max-h-[80vh] overflow-y-auto">
420
- <div className="flex items-center justify-between p-4 border-b border-gray-200">
421
- <h3 className="text-lg font-medium text-gray-900">{title}</h3>
422
- <button
423
- onClick={() => setShowPopover(false)}
424
- className="p-1 text-gray-400 hover:text-gray-600"
425
- >
426
- <XMarkIcon className="w-5 h-5" />
427
- </button>
428
- </div>
429
- <div className="p-4">{renderControls()}</div>
430
- </div>
431
- </div>
432
- </>
433
- )}
434
- </div>
435
- );
436
- }
437
-
438
- // presentation === 'inline'
439
- return (
440
- <div className={`border border-gray-200 rounded-lg p-4 ${className}`}>
441
- <h3 className="text-sm font-medium text-gray-900 mb-3 flex items-center">
442
- <CogIcon className="w-4 h-4 mr-2" />
443
- {title}
444
- </h3>
445
- {renderControls()}
446
- </div>
447
- );
448
- };
449
-
450
- export default ResolutionContextOptionsControl;