@fgv/ts-res-ui-components 5.0.0-16 → 5.0.0-18

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 (218) hide show
  1. package/README.md +705 -68
  2. package/config/api-extractor.json +89 -0
  3. package/dist/ts-res-ui-components.d.ts +4805 -0
  4. package/lib/components/common/QualifierContextControl.d.ts +76 -0
  5. package/lib/components/common/QualifierContextControl.js +64 -0
  6. package/lib/components/common/ResolutionResults/index.d.ts +138 -0
  7. package/lib/components/common/ResolutionResults/index.js +293 -0
  8. package/lib/components/common/ResourceListView.d.ts +104 -0
  9. package/lib/components/common/ResourceListView.js +94 -0
  10. package/lib/components/common/ResourcePickerOptionsControl.d.ts +43 -0
  11. package/lib/components/common/ResourcePickerOptionsControl.js +142 -0
  12. package/lib/components/common/ResourceTreeView.d.ts +141 -0
  13. package/lib/components/common/ResourceTreeView.js +131 -0
  14. package/lib/components/common/SourceResourceDetail/index.d.ts +125 -0
  15. package/lib/components/common/SourceResourceDetail/index.js +339 -0
  16. package/lib/components/forms/HierarchyEditor.d.ts +81 -0
  17. package/lib/components/forms/HierarchyEditor.js +72 -0
  18. package/lib/components/forms/QualifierEditForm.d.ts +97 -0
  19. package/lib/components/forms/QualifierEditForm.js +87 -0
  20. package/lib/components/forms/QualifierTypeEditForm.d.ts +111 -0
  21. package/lib/components/forms/QualifierTypeEditForm.js +102 -0
  22. package/lib/components/forms/ResourceTypeEditForm.d.ts +106 -0
  23. package/lib/components/forms/ResourceTypeEditForm.js +97 -0
  24. package/lib/components/orchestrator/ResourceOrchestrator.js +6 -2
  25. package/lib/components/pickers/ResourcePicker/ResourceItem.d.ts +8 -0
  26. package/lib/components/pickers/ResourcePicker/ResourceItem.js +55 -0
  27. package/lib/components/pickers/ResourcePicker/ResourcePickerList.d.ts +9 -0
  28. package/lib/components/pickers/ResourcePicker/ResourcePickerList.js +71 -0
  29. package/lib/components/pickers/ResourcePicker/ResourcePickerTree.d.ts +9 -0
  30. package/lib/components/pickers/ResourcePicker/ResourcePickerTree.js +301 -0
  31. package/lib/components/pickers/ResourcePicker/index.d.ts +61 -0
  32. package/lib/components/pickers/ResourcePicker/index.js +133 -0
  33. package/lib/components/pickers/ResourcePicker/types.d.ts +288 -0
  34. package/lib/components/pickers/ResourcePicker/utils/treeNavigation.d.ts +44 -0
  35. package/lib/components/pickers/ResourcePicker/utils/treeNavigation.js +147 -0
  36. package/lib/components/views/CompiledView/index.d.ts +39 -0
  37. package/lib/components/views/CompiledView/index.js +251 -37
  38. package/lib/components/views/ConfigurationView/index.d.ts +46 -0
  39. package/lib/components/views/ConfigurationView/index.js +46 -0
  40. package/lib/components/views/FilterView/index.d.ts +48 -0
  41. package/lib/components/views/FilterView/index.js +136 -224
  42. package/lib/components/views/ImportView/index.d.ts +47 -0
  43. package/lib/components/views/ImportView/index.js +101 -37
  44. package/lib/components/views/MessagesWindow/index.d.ts +128 -0
  45. package/lib/components/views/MessagesWindow/index.js +189 -0
  46. package/lib/components/views/ResolutionView/EditableJsonView.d.ts +171 -0
  47. package/lib/components/views/ResolutionView/EditableJsonView.js +166 -0
  48. package/lib/components/views/ResolutionView/ResolutionEditControls.d.ts +133 -0
  49. package/lib/components/views/ResolutionView/ResolutionEditControls.js +128 -0
  50. package/lib/components/views/ResolutionView/index.d.ts +49 -0
  51. package/lib/components/views/ResolutionView/index.js +148 -169
  52. package/lib/components/views/SourceView/index.d.ts +36 -0
  53. package/lib/components/views/SourceView/index.js +69 -212
  54. package/lib/hooks/useConfigurationState.d.ts +63 -0
  55. package/lib/hooks/useConfigurationState.js +63 -0
  56. package/lib/hooks/useFilterState.d.ts +53 -0
  57. package/lib/hooks/useFilterState.js +46 -0
  58. package/lib/hooks/useResolutionState.d.ts +71 -0
  59. package/lib/hooks/useResolutionState.js +63 -0
  60. package/lib/hooks/useViewState.d.ts +53 -0
  61. package/lib/hooks/useViewState.js +43 -0
  62. package/lib/index.d.ts +7 -17
  63. package/lib/index.js +32 -22
  64. package/lib/namespaces/ConfigurationTools.d.ts +44 -0
  65. package/lib/namespaces/ConfigurationTools.js +47 -0
  66. package/lib/namespaces/FilterTools.d.ts +34 -0
  67. package/lib/namespaces/FilterTools.js +36 -0
  68. package/lib/namespaces/ImportTools.d.ts +32 -0
  69. package/lib/namespaces/ImportTools.js +33 -0
  70. package/lib/namespaces/PickerTools.d.ts +90 -0
  71. package/lib/namespaces/PickerTools.js +90 -0
  72. package/lib/namespaces/ResolutionTools.d.ts +38 -0
  73. package/lib/namespaces/ResolutionTools.js +40 -0
  74. package/lib/namespaces/ResourceTools.d.ts +95 -0
  75. package/lib/namespaces/ResourceTools.js +95 -0
  76. package/lib/namespaces/TsResTools.d.ts +37 -0
  77. package/lib/namespaces/TsResTools.js +38 -0
  78. package/lib/namespaces/ViewStateTools.d.ts +84 -0
  79. package/lib/namespaces/ViewStateTools.js +84 -0
  80. package/lib/namespaces/ZipTools.d.ts +42 -0
  81. package/lib/namespaces/ZipTools.js +44 -0
  82. package/lib/namespaces/index.d.ts +49 -0
  83. package/lib/namespaces/index.js +49 -0
  84. package/lib/test/unit/ResourcePicker.test.d.ts +9 -0
  85. package/lib/tsdoc-metadata.json +11 -0
  86. package/lib/types/index.d.ts +636 -10
  87. package/lib/utils/configurationUtils.d.ts +153 -0
  88. package/lib/utils/configurationUtils.js +149 -0
  89. package/lib/utils/fileProcessing.d.ts +4 -0
  90. package/lib/utils/fileProcessing.js +4 -0
  91. package/lib/utils/filterResources.d.ts +168 -16
  92. package/lib/utils/filterResources.js +159 -2
  93. package/lib/utils/resolutionUtils.d.ts +456 -5
  94. package/lib/utils/resolutionUtils.js +413 -5
  95. package/lib/utils/tsResIntegration.d.ts +6 -0
  96. package/lib/utils/tsResIntegration.js +6 -0
  97. package/lib/utils/zipLoader/index.d.ts +2 -7
  98. package/lib/utils/zipLoader/index.js +4 -12
  99. package/lib/utils/zipLoader/zipProcessingHelpers.d.ts +18 -0
  100. package/lib/utils/zipLoader/zipProcessingHelpers.js +43 -0
  101. package/lib/utils/zipLoader/zipUtils.d.ts +1 -48
  102. package/lib/utils/zipLoader/zipUtils.js +1 -222
  103. package/lib-commonjs/components/common/QualifierContextControl.js +64 -0
  104. package/lib-commonjs/components/common/ResolutionResults/index.js +298 -0
  105. package/lib-commonjs/components/common/ResourceListView.js +94 -0
  106. package/lib-commonjs/components/common/ResourcePickerOptionsControl.js +147 -0
  107. package/lib-commonjs/components/common/ResourceTreeView.js +131 -0
  108. package/lib-commonjs/components/common/SourceResourceDetail/index.js +344 -0
  109. package/lib-commonjs/components/forms/HierarchyEditor.js +72 -0
  110. package/lib-commonjs/components/forms/QualifierEditForm.js +87 -0
  111. package/lib-commonjs/components/forms/QualifierTypeEditForm.js +102 -0
  112. package/lib-commonjs/components/forms/ResourceTypeEditForm.js +97 -0
  113. package/lib-commonjs/components/orchestrator/ResourceOrchestrator.js +6 -2
  114. package/lib-commonjs/components/pickers/ResourcePicker/ResourceItem.js +60 -0
  115. package/lib-commonjs/components/pickers/ResourcePicker/ResourcePickerList.js +76 -0
  116. package/lib-commonjs/components/pickers/ResourcePicker/ResourcePickerTree.js +306 -0
  117. package/lib-commonjs/components/pickers/ResourcePicker/index.js +138 -0
  118. package/lib-commonjs/components/pickers/ResourcePicker/utils/treeNavigation.js +156 -0
  119. package/lib-commonjs/components/views/CompiledView/index.js +251 -37
  120. package/lib-commonjs/components/views/ConfigurationView/index.js +46 -0
  121. package/lib-commonjs/components/views/FilterView/index.js +135 -223
  122. package/lib-commonjs/components/views/ImportView/index.js +100 -36
  123. package/lib-commonjs/components/views/MessagesWindow/index.js +194 -0
  124. package/lib-commonjs/components/views/ResolutionView/EditableJsonView.js +166 -0
  125. package/lib-commonjs/components/views/ResolutionView/ResolutionEditControls.js +128 -0
  126. package/lib-commonjs/components/views/ResolutionView/index.js +147 -168
  127. package/lib-commonjs/components/views/SourceView/index.js +68 -211
  128. package/lib-commonjs/hooks/useConfigurationState.js +63 -0
  129. package/lib-commonjs/hooks/useFilterState.js +46 -0
  130. package/lib-commonjs/hooks/useResolutionState.js +63 -0
  131. package/lib-commonjs/hooks/useViewState.js +43 -0
  132. package/lib-commonjs/index.js +45 -38
  133. package/lib-commonjs/namespaces/ConfigurationTools.js +61 -0
  134. package/lib-commonjs/namespaces/FilterTools.js +45 -0
  135. package/lib-commonjs/namespaces/ImportTools.js +41 -0
  136. package/lib-commonjs/namespaces/PickerTools.js +95 -0
  137. package/lib-commonjs/namespaces/ResolutionTools.js +53 -0
  138. package/lib-commonjs/namespaces/ResourceTools.js +99 -0
  139. package/lib-commonjs/namespaces/TsResTools.js +49 -0
  140. package/lib-commonjs/namespaces/ViewStateTools.js +89 -0
  141. package/lib-commonjs/namespaces/ZipTools.js +51 -0
  142. package/lib-commonjs/namespaces/index.js +53 -0
  143. package/lib-commonjs/utils/configurationUtils.js +149 -0
  144. package/lib-commonjs/utils/fileProcessing.js +4 -0
  145. package/lib-commonjs/utils/filterResources.js +159 -2
  146. package/lib-commonjs/utils/resolutionUtils.js +413 -5
  147. package/lib-commonjs/utils/tsResIntegration.js +6 -0
  148. package/lib-commonjs/utils/zipLoader/index.js +6 -25
  149. package/lib-commonjs/utils/zipLoader/zipProcessingHelpers.js +47 -0
  150. package/lib-commonjs/utils/zipLoader/zipUtils.js +1 -233
  151. package/package.json +11 -7
  152. package/src/components/common/QualifierContextControl.tsx +76 -0
  153. package/src/components/common/ResolutionResults/index.tsx +481 -0
  154. package/src/components/common/ResourceListView.tsx +104 -0
  155. package/src/components/common/ResourcePickerOptionsControl.tsx +351 -0
  156. package/src/components/common/ResourceTreeView.tsx +146 -0
  157. package/src/components/common/SourceResourceDetail/index.tsx +493 -0
  158. package/src/components/forms/HierarchyEditor.tsx +81 -0
  159. package/src/components/forms/QualifierEditForm.tsx +97 -0
  160. package/src/components/forms/QualifierTypeEditForm.tsx +111 -0
  161. package/src/components/forms/ResourceTypeEditForm.tsx +106 -0
  162. package/src/components/orchestrator/ResourceOrchestrator.tsx +7 -4
  163. package/src/components/pickers/ResourcePicker/README.md +570 -0
  164. package/src/components/pickers/ResourcePicker/ResourceItem.tsx +127 -0
  165. package/src/components/pickers/ResourcePicker/ResourcePickerList.tsx +114 -0
  166. package/src/components/pickers/ResourcePicker/ResourcePickerTree.tsx +461 -0
  167. package/src/components/pickers/ResourcePicker/index.tsx +234 -0
  168. package/src/components/pickers/ResourcePicker/types.ts +301 -0
  169. package/src/components/pickers/ResourcePicker/utils/treeNavigation.ts +210 -0
  170. package/src/components/views/CompiledView/index.tsx +419 -42
  171. package/src/components/views/ConfigurationView/index.tsx +46 -0
  172. package/src/components/views/FilterView/index.tsx +182 -406
  173. package/src/components/views/ImportView/index.tsx +110 -38
  174. package/src/components/views/MessagesWindow/index.tsx +325 -0
  175. package/src/components/views/ResolutionView/EditableJsonView.tsx +171 -0
  176. package/src/components/views/ResolutionView/ResolutionEditControls.tsx +133 -0
  177. package/src/components/views/ResolutionView/index.tsx +191 -337
  178. package/src/components/views/SourceView/index.tsx +103 -350
  179. package/src/hooks/useConfigurationState.ts +63 -0
  180. package/src/hooks/useFilterState.ts +53 -0
  181. package/src/hooks/useResolutionState.ts +71 -0
  182. package/src/hooks/useViewState.ts +53 -0
  183. package/src/index.ts +53 -30
  184. package/src/namespaces/ConfigurationTools.ts +59 -0
  185. package/src/namespaces/FilterTools.ts +47 -0
  186. package/src/namespaces/ImportTools.ts +42 -0
  187. package/src/namespaces/PickerTools.ts +104 -0
  188. package/src/namespaces/ResolutionTools.ts +64 -0
  189. package/src/namespaces/ResourceTools.ts +106 -0
  190. package/src/namespaces/TsResTools.ts +49 -0
  191. package/src/namespaces/ViewStateTools.ts +91 -0
  192. package/src/namespaces/ZipTools.ts +49 -0
  193. package/src/namespaces/index.ts +49 -0
  194. package/src/types/index.ts +644 -14
  195. package/src/utils/configurationUtils.ts +153 -0
  196. package/src/utils/fileProcessing.ts +4 -0
  197. package/src/utils/filterResources.ts +168 -18
  198. package/src/utils/resolutionUtils.ts +456 -5
  199. package/src/utils/tsResIntegration.ts +6 -0
  200. package/src/utils/zipLoader/index.ts +4 -25
  201. package/src/utils/zipLoader/zipProcessingHelpers.ts +52 -0
  202. package/src/utils/zipLoader/zipUtils.ts +1 -260
  203. package/lib/components/views/ZipLoaderView/index.d.ts +0 -5
  204. package/lib/components/views/ZipLoaderView/index.js +0 -313
  205. package/lib/utils/zipLoader/browserZipLoader.d.ts +0 -52
  206. package/lib/utils/zipLoader/browserZipLoader.js +0 -224
  207. package/lib/utils/zipLoader/nodeZipBuilder.d.ts +0 -55
  208. package/lib/utils/zipLoader/nodeZipBuilder.js +0 -98
  209. package/lib/utils/zipLoader/types.d.ts +0 -139
  210. package/lib-commonjs/components/views/ZipLoaderView/index.js +0 -318
  211. package/lib-commonjs/utils/zipLoader/browserZipLoader.js +0 -231
  212. package/lib-commonjs/utils/zipLoader/nodeZipBuilder.js +0 -105
  213. package/src/components/views/ZipLoaderView/index.tsx +0 -485
  214. package/src/utils/zipLoader/browserZipLoader.ts +0 -324
  215. package/src/utils/zipLoader/nodeZipBuilder.ts +0 -153
  216. package/src/utils/zipLoader/types.ts +0 -175
  217. /package/lib/{utils/zipLoader → components/pickers/ResourcePicker}/types.js +0 -0
  218. /package/lib-commonjs/{utils/zipLoader → components/pickers/ResourcePicker}/types.js +0 -0
package/README.md CHANGED
@@ -16,9 +16,20 @@ This packlet is largely AI written, and it shows.
16
16
  - **🎯 Resource Resolution**: Test resource resolution with dynamic context values
17
17
  - **📊 Visualization**: Multiple views for exploring resource structures and compiled output
18
18
  - **⚙️ Configuration**: Visual configuration management for qualifier types, qualifiers, and resource types
19
- - **📁 File Handling**: Support for directory imports, ZIP files, and bundle loading
19
+ - **📁 File Handling**: Support for directory imports, ZIP files via ts-res zip-archive packlet, and bundle loading
20
20
  - **🎨 Modern UI**: Built with Tailwind CSS and Heroicons for a clean, responsive interface
21
21
 
22
+ ### ZIP Archive Integration
23
+
24
+ This library now uses the **ts-res zip-archive packlet** as the single source of truth for all ZIP operations, providing:
25
+
26
+ - **Universal compatibility**: Works in both browser and Node.js environments using fflate
27
+ - **Standardized format**: Common ZIP bundle format across all ts-res tools
28
+ - **Simplified API**: Direct integration with ts-res ZIP archive functionality
29
+ - **Processing helpers**: Utilities to integrate ZIP data with ts-res-ui-components workflows
30
+
31
+ The `ImportView` component handles ZIP files automatically, and the `ZipTools` namespace provides processing helpers for custom ZIP workflows.
32
+
22
33
  ## Installation
23
34
 
24
35
  ```bash
@@ -116,24 +127,32 @@ function MyResourceViewer() {
116
127
 
117
128
  ```
118
129
  ResourceOrchestrator (state management)
119
- ├── ImportView (file/bundle import)
130
+ ├── ImportView (file/bundle/ZIP import)
120
131
  ├── SourceView (resource collection display)
121
132
  ├── FilterView (context filtering)
122
133
  ├── CompiledView (compiled resource structure)
123
134
  ├── ResolutionView (resource resolution testing)
124
- ├── ConfigurationView (system configuration)
125
- └── ZipLoaderView (ZIP file handling)
135
+ └── ConfigurationView (system configuration)
126
136
  ```
127
137
 
128
138
  ### Data Flow
129
139
 
130
- 1. **Import Phase**: Resources are imported via `ImportView` or programmatically
131
- 2. **Processing Phase**: Raw files are processed into a `ProcessedResources` object containing:
140
+ 1. **Configuration Phase**: System configuration is created or managed via `ConfigurationView`
141
+ - Define qualifier types (language, territory, platform, etc.)
142
+ - Configure qualifiers and their default values
143
+ - Set up resource types and validation rules
144
+ 2. **Import Phase**: Resources are imported via `ImportView` or programmatically
145
+ - Individual JSON files, directories, ZIP bundles, or pre-compiled collections
146
+ - Configuration can be imported alongside resources or applied separately
147
+ 3. **Processing Phase**: Raw files are processed into a `ProcessedResources` object containing:
132
148
  - `ResourceManagerBuilder` for build-time operations
133
149
  - `CompiledResourceCollection` for runtime efficiency
134
150
  - `ResourceResolver` for resource resolution
135
- 3. **Interaction Phase**: Users can filter, explore, and test resource resolution
136
- 4. **Export Phase**: Processed resources can be exported as JSON or compiled bundles
151
+ 4. **Interaction Phase**: Users can filter, explore, and test resource resolution
152
+ - Filter resources with context values using `FilterView`
153
+ - Browse source and compiled structures with `SourceView` and `CompiledView`
154
+ - Test resolution with different contexts using `ResolutionView`
155
+ 5. **Export Phase**: Processed resources can be exported as JSON or compiled bundles
137
156
 
138
157
  ### Key Concepts
139
158
 
@@ -149,6 +168,8 @@ ResourceOrchestrator (state management)
149
168
 
150
169
  The main orchestration component that manages all state and provides actions via render props.
151
170
 
171
+ > 📚 **[See ResourceOrchestrator documentation →](./docs/ts-res-ui-components.resourceorchestrator.md)**
172
+
152
173
  ```tsx
153
174
  <ResourceOrchestrator
154
175
  initialConfiguration={myConfig}
@@ -160,36 +181,150 @@ The main orchestration component that manages all state and provides actions via
160
181
  </ResourceOrchestrator>
161
182
  ```
162
183
 
184
+ ### ConfigurationView
185
+
186
+ Visual configuration management for ts-res system settings including qualifier types, qualifiers, and resource types.
187
+
188
+ > 📚 **[See ConfigurationView documentation →](./docs/ts-res-ui-components.configurationview.md)**
189
+
190
+ ```tsx
191
+ <ConfigurationView
192
+ configuration={state.activeConfiguration}
193
+ onConfigurationChange={actions.applyConfiguration}
194
+ onSave={actions.saveConfiguration}
195
+ hasUnsavedChanges={state.hasConfigurationChanges}
196
+ onMessage={(type, message) => console.log(type, message)}
197
+ />
198
+ ```
199
+
200
+ **Key features:**
201
+ - **Qualifier type management**: Define language, territory, platform, and custom qualifier types
202
+ - **Qualifier configuration**: Set up specific qualifiers with default values and validation
203
+ - **Resource type management**: Configure resource types and their validation rules
204
+ - **Import/export**: Load configurations from files or export current settings
205
+ - **Real-time validation**: Validate configuration changes as you edit
206
+ - **Change tracking**: Visual indicators for unsaved changes
207
+
163
208
  ### ImportView
164
209
 
165
- Handles importing resource files, directories, bundles, and ZIP files.
210
+ Handles importing resource files, directories, bundles, and ZIP files. Uses the ts-res zip-archive packlet for all ZIP operations.
211
+
212
+ > 📚 **[See ImportView documentation →](./docs/ts-res-ui-components.importview.md)**
166
213
 
167
214
  ```tsx
168
215
  <ImportView
169
216
  onImport={actions.importDirectory}
170
217
  onBundleImport={actions.importBundle}
171
- onZipImport={actions.importZipWithConfig}
218
+ onZipImport={(zipData, config) => {
219
+ // zipData contains files and directory structure from ZIP
220
+ // config contains any configuration found in the ZIP
221
+ actions.importDirectory(zipData, config);
222
+ }}
172
223
  acceptedFileTypes={['.json', '.ts', '.js']}
173
224
  onMessage={(type, message) => console.log(type, message)}
174
225
  />
175
226
  ```
176
227
 
228
+ ### ResourcePicker
229
+
230
+ Core component for browsing and selecting resources with advanced features like search, annotations, and pending resource support. The resource picker
231
+ is a generic component used by all of the views, which can also be used to power other application-specific views.
232
+
233
+ > 📚 **[See complete ResourcePicker documentation →](./docs/ts-res-ui-components.resourcepicker.md)**
234
+
235
+ ```tsx
236
+ <ResourcePicker
237
+ resources={state.processedResources}
238
+ selectedResourceId={selectedId}
239
+ onResourceSelect={(selection) => {
240
+ setSelectedId(selection.resourceId);
241
+ // Access resource data directly without additional lookups
242
+ if (selection.resourceData) {
243
+ handleResourceData(selection.resourceData);
244
+ }
245
+ // Handle pending resources
246
+ if (selection.isPending) {
247
+ console.log(`Pending ${selection.pendingType} operation`);
248
+ }
249
+ }}
250
+ options={{
251
+ defaultView: "tree",
252
+ enableSearch: true,
253
+ searchPlaceholder: "Search resources...",
254
+ height: "500px"
255
+ }}
256
+ resourceAnnotations={{
257
+ 'user.welcome': {
258
+ badge: { text: '3', variant: 'info' },
259
+ suffix: '(3 candidates)'
260
+ }
261
+ }}
262
+ pendingResources={pendingChanges}
263
+ />
264
+ ```
265
+
266
+ **Key features:**
267
+ - **Enhanced callbacks**: Get resource data and metadata in selection callback
268
+ - **Multiple view modes**: List and tree views with search
269
+ - **Visual annotations**: Badges, indicators, and suffixes
270
+ - **Pending resources**: Show unsaved changes with visual distinction
271
+ - **Branch isolation**: Focus on specific parts of large resource trees
272
+ - **Type safety**: Full TypeScript support with generic resource types
273
+ - **Debug controls**: Optional ResourcePickerOptionsControl for development and debugging
274
+
275
+ #### ResourcePickerOptionsControl
276
+
277
+ A debugging/design tool for interactively configuring ResourcePicker behavior. Hidden by default for production use, but can be enabled in development:
278
+
279
+ ```tsx
280
+ // All view components support pickerOptionsPresentation
281
+ <SourceView
282
+ resources={state.processedResources}
283
+ pickerOptionsPresentation="collapsible" // Enable picker options UI
284
+ onMessage={(type, message) => console.log(`${type}: ${message}`)}
285
+ />
286
+
287
+ // Direct usage in custom components
288
+ <PickerTools.ResourcePickerOptionsControl
289
+ options={pickerOptions}
290
+ onOptionsChange={setPickerOptions}
291
+ presentation="popup" // 'hidden' | 'inline' | 'collapsible' | 'popup' | 'popover'
292
+ title="Picker Configuration"
293
+ showAdvanced={true}
294
+ />
295
+ ```
296
+
297
+ **Presentation modes:**
298
+ - `'hidden'`: Not displayed (default for production)
299
+ - `'inline'`: Always visible with expanded controls
300
+ - `'collapsible'`: Expandable/collapsible section
301
+ - `'popup'`: Full modal dialog overlay
302
+ - `'popover'`: Small dropdown overlay
303
+
177
304
  ### SourceView
178
305
 
179
- Displays the source resource collection with search and navigation capabilities.
306
+ Displays the source resource collection with search and navigation capabilities using the enhanced ResourcePicker.
307
+
308
+ > 📚 **[See SourceView documentation →](./docs/ts-res-ui-components.sourceview.md)**
180
309
 
181
310
  ```tsx
182
311
  <SourceView
183
312
  resources={state.processedResources}
184
- selectedResourceId={selectedId}
185
- onResourceSelect={setSelectedId}
186
313
  onExport={actions.exportData}
314
+ onMessage={(type, message) => console.log(`${type}: ${message}`)}
315
+ pickerOptions={{
316
+ defaultView: "list",
317
+ enableSearch: true,
318
+ searchPlaceholder: "Search resources..."
319
+ }}
187
320
  />
188
321
  ```
189
322
 
190
323
  ### FilterView
191
324
 
192
- Provides filtering capabilities with context value specification.
325
+ Provides filtering capabilities with context value specification and dual-resource comparison.
326
+
327
+ > 📚 **[See FilterView documentation →](./docs/ts-res-ui-components.filterview.md)**
193
328
 
194
329
  ```tsx
195
330
  <FilterView
@@ -198,12 +333,19 @@ Provides filtering capabilities with context value specification.
198
333
  filterActions={filterActions}
199
334
  filterResult={filterResult}
200
335
  onFilterResult={setFilterResult}
336
+ onMessage={(type, message) => console.log(`${type}: ${message}`)}
337
+ pickerOptions={{
338
+ enableSearch: true,
339
+ searchPlaceholder: "Search resources..."
340
+ }}
201
341
  />
202
342
  ```
203
343
 
204
344
  ### CompiledView
205
345
 
206
- Shows the compiled resource structure with detailed candidate information.
346
+ Shows the compiled resource structure with detailed candidate information using the enhanced ResourcePicker.
347
+
348
+ > 📚 **[See CompiledView documentation →](./docs/ts-res-ui-components.compiledview.md)**
207
349
 
208
350
  ```tsx
209
351
  <CompiledView
@@ -211,12 +353,19 @@ Shows the compiled resource structure with detailed candidate information.
211
353
  filterResult={filterResult}
212
354
  useNormalization={true}
213
355
  onExport={(data, type) => exportData(data, type)}
356
+ onMessage={(type, message) => console.log(`${type}: ${message}`)}
357
+ pickerOptions={{
358
+ defaultView: "tree",
359
+ enableSearch: true
360
+ }}
214
361
  />
215
362
  ```
216
363
 
217
364
  ### ResolutionView
218
365
 
219
- Interactive resource resolution testing with context management.
366
+ Interactive resource resolution testing with context management and support for custom resource editors via the ResourceEditorFactory pattern.
367
+
368
+ > 📚 **[See ResolutionView documentation →](./docs/ts-res-ui-components.resolutionview.md)**
220
369
 
221
370
  ```tsx
222
371
  <ResolutionView
@@ -224,29 +373,235 @@ Interactive resource resolution testing with context management.
224
373
  resolutionState={resolutionState}
225
374
  resolutionActions={resolutionActions}
226
375
  availableQualifiers={availableQualifiers}
376
+ resourceEditorFactory={myResourceEditorFactory}
377
+ onMessage={(type, message) => console.log(`${type}: ${message}`)}
378
+ pickerOptions={{
379
+ defaultView: "list",
380
+ enableSearch: true,
381
+ searchPlaceholder: "Search resources for resolution testing..."
382
+ }}
227
383
  />
228
384
  ```
229
385
 
230
- ### ConfigurationView
386
+ #### Custom Resource Editors
231
387
 
232
- Visual configuration management for the ts-res system.
388
+ The ResolutionView supports custom editors for specific resource types through the `ResourceEditorFactory` interface:
233
389
 
234
390
  ```tsx
235
- <ConfigurationView
236
- configuration={state.activeConfiguration}
237
- onConfigurationChange={actions.applyConfiguration}
238
- onMessage={(type, msg) => showMessage(type, msg)}
391
+ import { ResourceEditorFactory, ResourceEditorResult, ResourceEditorProps } from '@fgv/ts-res-ui-components';
392
+
393
+ // Custom editor component
394
+ const MarketInfoEditor: React.FC<ResourceEditorProps> = ({
395
+ value,
396
+ resourceId,
397
+ isEdited,
398
+ editedValue,
399
+ onSave,
400
+ onCancel,
401
+ disabled,
402
+ className
403
+ }) => {
404
+ // Custom form-based editor implementation
405
+ return (
406
+ <div className={`market-info-editor ${className}`}>
407
+ {/* Custom editing interface for market information */}
408
+ </div>
409
+ );
410
+ };
411
+
412
+ // Resource editor factory
413
+ class MyResourceEditorFactory implements ResourceEditorFactory {
414
+ createEditor(resourceId: string, resourceType: string, value: any): ResourceEditorResult {
415
+ if (resourceType === 'marketInfo') {
416
+ return {
417
+ success: true,
418
+ editor: MarketInfoEditor
419
+ };
420
+ }
421
+
422
+ return {
423
+ success: false,
424
+ message: `No custom editor available for resource type '${resourceType}'`
425
+ };
426
+ }
427
+ }
428
+
429
+ // Usage
430
+ const editorFactory = new MyResourceEditorFactory();
431
+
432
+ <ResolutionView
433
+ resources={resources}
434
+ resourceEditorFactory={editorFactory}
435
+ // ... other props
239
436
  />
240
437
  ```
241
438
 
439
+ **Benefits of Custom Editors:**
440
+ - **Type-Specific UX**: Provide structured editing interfaces for different resource types
441
+ - **Graceful Fallback**: Unknown resource types automatically fall back to JSON editor
442
+ - **Extensible**: Easy to add new editors for new resource types
443
+ - **Error Handling**: Factory failures are caught and reported to users
444
+
445
+ ### MessagesWindow
446
+
447
+ Displays and manages application messages with filtering, search, and copy functionality. Perfect for debugging interfaces and development tools where message visibility is critical.
448
+
449
+ > 📚 **[See MessagesWindow documentation →](./docs/ts-res-ui-components.messageswindow.md)**
450
+
451
+ ```tsx
452
+ import { MessagesWindow, ViewTools } from '@fgv/ts-res-ui-components';
453
+
454
+ function MyApplication() {
455
+ const [messages, setMessages] = useState<ViewTools.Message[]>([]);
456
+
457
+ const addMessage = (type: ViewTools.Message['type'], text: string) => {
458
+ const newMessage: ViewTools.Message = {
459
+ id: `msg-${Date.now()}-${Math.random()}`,
460
+ type,
461
+ message: text,
462
+ timestamp: new Date()
463
+ };
464
+ setMessages(prev => [...prev, newMessage]);
465
+ };
466
+
467
+ const clearMessages = () => {
468
+ setMessages([]);
469
+ };
470
+
471
+ return (
472
+ <div className="flex flex-col h-screen">
473
+ <div className="flex-1">
474
+ {/* Main application content */}
475
+ <button onClick={() => addMessage('info', 'Processing started')}>
476
+ Add Info Message
477
+ </button>
478
+ <button onClick={() => addMessage('success', 'Operation completed')}>
479
+ Add Success Message
480
+ </button>
481
+ <button onClick={() => addMessage('error', 'Something went wrong')}>
482
+ Add Error Message
483
+ </button>
484
+ </div>
485
+
486
+ {/* Messages window at bottom */}
487
+ <MessagesWindow
488
+ messages={messages}
489
+ onClearMessages={clearMessages}
490
+ />
491
+ </div>
492
+ );
493
+ }
494
+ ```
495
+
496
+ **Key features:**
497
+ - **Message filtering**: Filter by type (info, warning, error, success) with count indicators
498
+ - **Search functionality**: Full-text search across message content
499
+ - **Copy functionality**: Copy all filtered messages to clipboard with timestamps
500
+ - **Collapsible interface**: Minimize/maximize to save screen space
501
+ - **Auto-hide when empty**: Component automatically hides when no messages exist
502
+ - **Visual indicators**: Color-coded message types with appropriate icons
503
+ - **Timestamp formatting**: Human-readable timestamp display
504
+
505
+ #### Adding Messages to Your Application
506
+
507
+ To integrate MessagesWindow into your application and provide user feedback during operations:
508
+
509
+ ```tsx
510
+ import { ViewTools } from '@fgv/ts-res-ui-components';
511
+
512
+ function useMessages() {
513
+ const [messages, setMessages] = useState<ViewTools.Message[]>([]);
514
+
515
+ const addMessage = useCallback((type: ViewTools.Message['type'], message: string) => {
516
+ const newMessage: ViewTools.Message = {
517
+ id: `msg-${Date.now()}-${Math.random()}`,
518
+ type,
519
+ message,
520
+ timestamp: new Date()
521
+ };
522
+ setMessages(prev => [...prev, newMessage]);
523
+ }, []);
524
+
525
+ const clearMessages = useCallback(() => {
526
+ setMessages([]);
527
+ }, []);
528
+
529
+ return { messages, addMessage, clearMessages };
530
+ }
531
+
532
+ function MyResourceTool() {
533
+ const { messages, addMessage, clearMessages } = useMessages();
534
+ const [resources, setResources] = useState(null);
535
+
536
+ const handleFileImport = async (files) => {
537
+ try {
538
+ addMessage('info', 'Starting file import...');
539
+ const processed = await processFiles(files);
540
+ setResources(processed);
541
+ addMessage('success', `Successfully imported ${files.length} files`);
542
+ } catch (error) {
543
+ addMessage('error', `Import failed: ${error.message}`);
544
+ }
545
+ };
546
+
547
+ const handleResourceFilter = (filterValues) => {
548
+ if (Object.keys(filterValues).length === 0) {
549
+ addMessage('warning', 'No filter values provided');
550
+ return;
551
+ }
552
+
553
+ try {
554
+ const filtered = applyFilters(resources, filterValues);
555
+ addMessage('success', `Filtered to ${filtered.length} resources`);
556
+ } catch (error) {
557
+ addMessage('error', `Filter failed: ${error.message}`);
558
+ }
559
+ };
560
+
561
+ return (
562
+ <div className="flex flex-col h-screen">
563
+ <div className="flex-1">
564
+ <ImportView onImport={handleFileImport} onMessage={addMessage} />
565
+ <FilterView onFilter={handleResourceFilter} onMessage={addMessage} />
566
+ {/* Other components that use onMessage callback */}
567
+ </div>
568
+
569
+ <ViewTools.MessagesWindow
570
+ messages={messages}
571
+ onClearMessages={clearMessages}
572
+ />
573
+ </div>
574
+ );
575
+ }
576
+ ```
577
+
578
+ **Common patterns for adding messages:**
579
+ - **info**: Operation started, processing steps, configuration loaded
580
+ - **success**: Operations completed successfully, files imported, resources processed
581
+ - **warning**: Non-critical issues, fallback behaviors, deprecated features used
582
+ - **error**: Operation failures, validation errors, unexpected conditions
583
+
584
+ **Message callback integration:**
585
+ Most components in this library accept an `onMessage` callback prop that you can connect to your message system. This provides consistent feedback across all operations.
586
+
242
587
  ## Hooks API
243
588
 
244
- ### useResourceData
589
+ > 📚 **[See complete hooks documentation →](./docs/ts-res-ui-components.md)** for detailed examples and patterns
590
+
591
+ All hooks are organized within their respective namespaces alongside their related components and utilities for better discoverability and logical grouping.
592
+
593
+ ### Core Data Management
245
594
 
246
- Main hook for resource processing and management.
595
+ #### ResourceTools.useResourceData
596
+
597
+ Main orchestrator hook for resource processing, configuration, and resolution.
598
+
599
+ > 📚 **[useResourceData documentation →](./docs/ts-res-ui-components.resourcetools.useresourcedata.md)**
247
600
 
248
601
  ```tsx
249
- const { state, actions } = useResourceData();
602
+ import { ResourceTools } from '@fgv/ts-res-ui-components';
603
+
604
+ const { state, actions } = ResourceTools.useResourceData();
250
605
 
251
606
  // Process files
252
607
  await actions.processFiles(importedFiles);
@@ -259,58 +614,157 @@ const result = await actions.resolveResource('my.resource', {
259
614
 
260
615
  // Apply configuration
261
616
  actions.applyConfiguration(newConfig);
617
+
618
+ // Check processing state
619
+ if (state.isProcessing) {
620
+ console.log('Processing resources...');
621
+ } else if (state.error) {
622
+ console.error('Processing failed:', state.error);
623
+ } else if (state.processedResources) {
624
+ console.log('Resources ready!');
625
+ }
262
626
  ```
263
627
 
264
- ### useFilterState
628
+ ### View State Management
265
629
 
266
- Manages resource filtering state and actions.
630
+ #### ViewTools.useViewState
631
+
632
+ Manages view state including messages and resource selection.
633
+
634
+ > 📚 **[useViewState documentation →](./docs/ts-res-ui-components.viewtools.useviewstate.md)**
267
635
 
268
636
  ```tsx
269
- const { filterState, filterActions } = useFilterState();
637
+ import { ViewTools } from '@fgv/ts-res-ui-components';
270
638
 
271
- // Update filter values
272
- filterActions.updateFilterValues({
273
- language: 'en-US',
274
- environment: 'prod'
639
+ const { messages, selectedResourceId, addMessage, clearMessages, selectResource } = ViewTools.useViewState();
640
+
641
+ // Display operation feedback
642
+ const handleOperation = async () => {
643
+ try {
644
+ await someAsyncOperation();
645
+ addMessage('success', 'Operation completed successfully');
646
+ } catch (error) {
647
+ addMessage('error', `Operation failed: ${error.message}`);
648
+ }
649
+ };
650
+
651
+ // Use with MessagesWindow component
652
+ return (
653
+ <div>
654
+ <button onClick={handleOperation}>Run Operation</button>
655
+ <ViewTools.MessagesWindow
656
+ messages={messages}
657
+ onClearMessages={clearMessages}
658
+ />
659
+ </div>
660
+ );
661
+ ```
662
+
663
+ ### Domain-Specific Hooks
664
+
665
+ #### FilterTools.useFilterState
666
+
667
+ Manages resource filtering state with change tracking and validation.
668
+
669
+ > 📚 **[useFilterState documentation →](./docs/ts-res-ui-components.filtertools.usefilterstate.md)**
670
+
671
+ ```tsx
672
+ import { FilterTools } from '@fgv/ts-res-ui-components';
673
+
674
+ const { state, actions } = FilterTools.useFilterState({
675
+ enabled: true,
676
+ values: { platform: 'web', locale: 'en' }
275
677
  });
276
678
 
277
- // Apply filters
278
- filterActions.applyFilterValues();
679
+ // Update filter values with change tracking
680
+ actions.updateFilterValue('language', 'en-US');
681
+ actions.updateFilterValue('environment', 'prod');
279
682
 
280
- // Check if there are pending changes
281
- if (filterState.hasPendingChanges) {
282
- // Show save prompt
683
+ // Apply filters when ready
684
+ if (state.hasPendingChanges) {
685
+ actions.applyFilters();
283
686
  }
284
687
  ```
285
688
 
286
- ### useResolutionState
689
+ #### ResolutionTools.useResolutionState
287
690
 
288
- Manages resource resolution testing state.
691
+ Comprehensive state management for resource resolution and editing.
692
+
693
+ > 📚 **[useResolutionState documentation →](./docs/ts-res-ui-components.resolutiontools.useresolutionstate.md)**
289
694
 
290
695
  ```tsx
291
- const { state, actions } = useResolutionState(processedResources);
696
+ import { ResolutionTools } from '@fgv/ts-res-ui-components';
697
+
698
+ const { state, actions, availableQualifiers } = ResolutionTools.useResolutionState(
699
+ processedResources,
700
+ (type, message) => addMessage(type, message),
701
+ (updatedResources) => setProcessedResources(updatedResources)
702
+ );
292
703
 
293
704
  // Set context for resolution testing
294
- actions.setContextValues({ language: 'en-US' });
705
+ actions.updateContext({ language: 'en-US', platform: 'web' });
706
+
707
+ // Start editing a resource
708
+ actions.selectResource('user.welcome');
709
+ actions.startEditing();
295
710
 
296
- // Test resource resolution
297
- const result = await actions.resolveResource('test.resource');
711
+ // Save edits with validation
712
+ actions.saveEdit(editedValue);
298
713
  ```
299
714
 
300
- ### useConfigurationState
715
+ #### ConfigurationTools.useConfigurationState
301
716
 
302
- Manages system configuration state.
717
+ Manages system configuration state with change tracking and import/export capabilities.
303
718
 
304
- ```tsx
305
- const { configuration, updateConfiguration, resetConfiguration } = useConfigurationState();
719
+ > 📚 **[useConfigurationState documentation →](./docs/ts-res-ui-components.configurationtools.useconfigurationstate.md)**
306
720
 
307
- // Update qualifier types
308
- updateConfiguration({
309
- ...configuration,
310
- qualifierTypes: [...newQualifierTypes]
721
+ ```tsx
722
+ import { ConfigurationTools } from '@fgv/ts-res-ui-components';
723
+
724
+ const { state, actions, templates } = ConfigurationTools.useConfigurationState(
725
+ undefined,
726
+ (config) => console.log('Configuration changed:', config),
727
+ (hasChanges) => setHasUnsavedChanges(hasChanges)
728
+ );
729
+
730
+ // Load a template
731
+ const loadResult = actions.loadTemplate('minimal');
732
+
733
+ // Add a new qualifier with validation
734
+ actions.addQualifier({
735
+ name: 'language',
736
+ typeName: 'language',
737
+ defaultPriority: 100
311
738
  });
739
+
740
+ // Check for unsaved changes
741
+ if (state.hasUnsavedChanges) {
742
+ actions.applyConfiguration();
743
+ }
744
+
745
+ // Export configuration
746
+ const exportResult = actions.exportToJson({ pretty: true });
747
+ if (exportResult.isSuccess()) {
748
+ downloadFile(exportResult.value, 'configuration.json');
749
+ }
312
750
  ```
313
751
 
752
+ ### Hook Organization
753
+
754
+ All hooks are organized within logical namespaces alongside their related components and utilities:
755
+
756
+ - **`ResourceTools.useResourceData`** - Core data orchestration (import, processing, configuration, resolution)
757
+ - **`ViewTools.useViewState`** - View state management (messages, resource selection)
758
+ - **`FilterTools.useFilterState`** - Resource filtering with change tracking
759
+ - **`ResolutionTools.useResolutionState`** - Resource resolution and editing
760
+ - **`ConfigurationTools.useConfigurationState`** - System configuration management
761
+
762
+ This organization provides:
763
+ - **Better discoverability** - Related functionality grouped together
764
+ - **Logical imports** - `FilterTools.useFilterState` is self-documenting
765
+ - **Namespace consistency** - Matches the existing component organization pattern
766
+ - **Clear separation of concerns** - Each namespace has a specific domain focus
767
+
314
768
  ## Styling
315
769
 
316
770
  This library uses Tailwind CSS for styling. Make sure to include Tailwind CSS in your project:
@@ -353,7 +807,7 @@ All components accept a `className` prop for custom styling:
353
807
  ### Custom Resource Processing
354
808
 
355
809
  ```tsx
356
- import { processImportedDirectory, createTsResSystemFromConfig } from '@fgv/ts-res-ui-components';
810
+ import { TsResTools } from '@fgv/ts-res-ui-components';
357
811
 
358
812
  // Custom processing pipeline
359
813
  const customProcessor = async (files: ImportedFile[]) => {
@@ -364,7 +818,7 @@ const customProcessor = async (files: ImportedFile[]) => {
364
818
  const config = await createConfigFromFiles(processedFiles);
365
819
 
366
820
  // Create ts-res system
367
- const system = await createTsResSystemFromConfig(config);
821
+ const system = await TsResTools.createTsResSystemFromConfig(config);
368
822
 
369
823
  return system;
370
824
  };
@@ -437,9 +891,54 @@ The library provides comprehensive error handling through the state management s
437
891
  </ResourceOrchestrator>
438
892
  ```
439
893
 
894
+ ## Organized Tool Namespaces
895
+
896
+ For better organization and discoverability, utility functions are organized into logical namespaces alongside their related view components:
897
+
898
+ ```tsx
899
+ import {
900
+ FilterTools, // FilterView + filtering utilities
901
+ ResolutionTools, // ResolutionView + resolution utilities
902
+ ConfigurationTools, // ConfigurationView + configuration utilities
903
+ TsResTools, // SourceView, CompiledView + ts-res utilities
904
+ ViewTools, // MessagesWindow + view state utilities
905
+ ZipTools, // ImportView + ZIP processing helpers
906
+ FileTools // File processing utilities
907
+ } from '@fgv/ts-res-ui-components';
908
+
909
+ // Use view components from namespaces
910
+ <FilterTools.FilterView {...filterProps} />
911
+ <ResolutionTools.ResolutionView {...resolutionProps} />
912
+ <ViewTools.MessagesWindow {...messageProps} />
913
+ <TsResTools.SourceView {...sourceProps} />
914
+ <ZipTools.ImportView {...importProps} />
915
+
916
+ // Use utility functions from namespaces
917
+ const hasFilters = FilterTools.hasFilterValues(filterState.values);
918
+ const resolver = ResolutionTools.createResolverWithContext(resources, context);
919
+ const system = await TsResTools.createTsResSystemFromConfig(config);
920
+
921
+ // ZIP processing helpers for ts-res-ui-components integration
922
+ const processResult = await ZipTools.processZipLoadResult(zipData, config);
923
+ ```
924
+
925
+ ### Namespace Contents
926
+
927
+ - **[FilterTools](./docs/ts-res-ui-components.filtertools.md)**: FilterView, filter analysis, filtered resource creation
928
+ - **[ResolutionTools](./docs/ts-res-ui-components.resolutiontools.md)**: ResolutionView, resolution testing, context management
929
+ - **[ConfigurationTools](./docs/ts-res-ui-components.configurationtools.md)**: ConfigurationView, configuration validation, import/export
930
+ - **[TsResTools](./docs/ts-res-ui-components.tsrestools.md)**: SourceView, CompiledView, ts-res system integration
931
+ - **[ViewTools](./docs/ts-res-ui-components.viewtools.md)**: MessagesWindow, message management, view state utilities
932
+ - **[ZipTools](./docs/ts-res-ui-components.ziptools.md)**: ImportView, ZIP processing helpers, uses ts-res zip-archive packlet
933
+ - **[FileTools](./docs/ts-res-ui-components.filetools.md)**: File processing, import/export utilities
934
+
935
+ All components are also available at the top level for backward compatibility.
936
+
440
937
  ## TypeScript Support
441
938
 
442
- This library is written in TypeScript and provides comprehensive type definitions:
939
+ This library is written in TypeScript and provides comprehensive type definitions with enhanced support for resource selection and generic resource data.
940
+
941
+ > 📚 **[See complete type documentation →](./docs/ts-res-ui-components.md)**
443
942
 
444
943
  ```tsx
445
944
  import type {
@@ -447,18 +946,66 @@ import type {
447
946
  FilterState,
448
947
  ResolutionResult,
449
948
  Message,
450
- ImportedFile
949
+ ImportedFile,
950
+ // Enhanced ResourcePicker types
951
+ ResourceSelection,
952
+ ResourcePickerProps,
953
+ ResourceAnnotation,
954
+ ResourceAnnotations,
955
+ PendingResource,
956
+ // Custom editor factory types
957
+ ResourceEditorFactory,
958
+ ResourceEditorResult,
959
+ ResourceEditorProps,
960
+ // Hook return types
961
+ UseViewStateReturn,
962
+ UseFilterStateReturn,
963
+ UseResolutionStateReturn
964
+ } from '@fgv/ts-res-ui-components';
965
+
966
+ // Import organized namespaces for components and utilities
967
+ import {
968
+ FilterTools,
969
+ ResolutionTools,
970
+ TsResTools,
971
+ ZipTools
451
972
  } from '@fgv/ts-res-ui-components';
452
973
 
453
- // Type-safe component props
454
- interface MyComponentProps {
974
+ // Type-safe component with enhanced resource selection
975
+ interface MyResourceViewProps<T = unknown> {
455
976
  resources: ProcessedResources;
456
977
  onMessage: (type: Message['type'], message: string) => void;
978
+ onResourceSelect: (selection: ResourceSelection<T>) => void;
457
979
  }
458
980
 
459
- const MyComponent: React.FC<MyComponentProps> = ({ resources, onMessage }) => {
460
- // Component implementation
981
+ const MyResourceView = <T = unknown>({ resources, onMessage, onResourceSelect }: MyResourceViewProps<T>) => {
982
+ return (
983
+ <ResourcePicker<T>
984
+ resources={resources}
985
+ onResourceSelect={(selection) => {
986
+ // TypeScript knows selection has resourceId, resourceData, isPending, etc.
987
+ onResourceSelect(selection);
988
+ }}
989
+ resourceAnnotations={{
990
+ 'user.welcome': {
991
+ badge: { text: 'NEW', variant: 'new' },
992
+ suffix: '(3 candidates)'
993
+ }
994
+ }}
995
+ />
996
+ );
461
997
  };
998
+
999
+ // Type-safe custom editor factory
1000
+ class TypedResourceEditorFactory implements ResourceEditorFactory {
1001
+ createEditor(resourceId: string, resourceType: string, value: any): ResourceEditorResult {
1002
+ // Full type safety for factory pattern
1003
+ if (resourceType === 'marketInfo') {
1004
+ return { success: true, editor: MarketInfoEditor };
1005
+ }
1006
+ return { success: false, message: `No editor for ${resourceType}` };
1007
+ }
1008
+ }
462
1009
  ```
463
1010
 
464
1011
  ## Performance Considerations
@@ -477,24 +1024,101 @@ const MyComponent: React.FC<MyComponentProps> = ({ resources, onMessage }) => {
477
1024
 
478
1025
  ## Development
479
1026
 
480
- ### Building
1027
+ This library is part of a [Rush.js](https://rushjs.io/) monorepo. Rush is a build orchestrator for JavaScript monorepos that provides scalable build performance and consistent package management.
1028
+
1029
+ ### Rush Monorepo Setup
1030
+
1031
+ If you're new to this monorepo, follow these steps to get started:
1032
+
1033
+ 1. **Install Rush globally** (if not already installed):
1034
+ ```bash
1035
+ npm install -g @microsoft/rush
1036
+ ```
1037
+
1038
+ 2. **Clone the repository and install dependencies**:
1039
+ ```bash
1040
+ git clone https://github.com/ErikFortune/fgv.git
1041
+ cd fgv
1042
+ rush install
1043
+ ```
1044
+
1045
+ 3. **Build all projects** (including dependencies):
1046
+ ```bash
1047
+ rush build
1048
+ ```
1049
+
1050
+ > 📚 **Learn more about Rush**: [Official Rush Documentation](https://rushjs.io/pages/intro/get_started/)
1051
+
1052
+ ### Development Commands
1053
+
1054
+ All development commands use Rush's `rushx` tool to run scripts within this specific project:
1055
+
1056
+ #### Building
1057
+
1058
+ ```bash
1059
+ # Build this project only
1060
+ rushx build
1061
+
1062
+ # Build all projects in the monorepo (from root)
1063
+ rush build
1064
+ ```
1065
+
1066
+ #### Testing
481
1067
 
482
1068
  ```bash
483
- npm run build
1069
+ # Test this project (includes coverage by default)
1070
+ rushx test
1071
+
1072
+ # Test all projects in the monorepo (from root)
1073
+ rush test
1074
+
1075
+ # Test specific projects with dependencies
1076
+ rush test --to ts-res-ui-components
1077
+
1078
+ # Test only this project without dependencies
1079
+ rush test --only ts-res-ui-components
484
1080
  ```
485
1081
 
486
- ### Testing
1082
+ #### Linting
487
1083
 
488
1084
  ```bash
489
- npm test
1085
+ # Lint this project
1086
+ rushx lint
1087
+
1088
+ # Fix lint issues automatically
1089
+ rushx fixlint
1090
+
1091
+ # Lint all projects in the monorepo (from root)
1092
+ rush prettier
490
1093
  ```
491
1094
 
492
- ### Linting
1095
+ #### Other Useful Commands
493
1096
 
494
1097
  ```bash
495
- npm run lint
1098
+ # Clean build artifacts
1099
+ rushx clean
1100
+
1101
+ # Update dependencies (from repository root)
1102
+ rush update
1103
+
1104
+ # Add a new dependency to this project (from repository root)
1105
+ rush add -p <package-name>
1106
+
1107
+ # Check for security vulnerabilities (from repository root)
1108
+ rush audit
496
1109
  ```
497
1110
 
1111
+ ### Monorepo Structure
1112
+
1113
+ This library is located at `libraries/ts-res-ui-components/` within the monorepo and depends on several other libraries in the workspace:
1114
+
1115
+ - `@fgv/ts-res` - Core resource management library
1116
+ - `@fgv/ts-utils` - Utility functions and Result pattern
1117
+ - `@fgv/ts-json-base` - JSON validation and processing
1118
+ - `@fgv/ts-bcp47` - BCP47 language tag processing
1119
+
1120
+ All workspace dependencies use `workspace:*` version ranges for automatic version resolution.
1121
+
498
1122
  ## License
499
1123
 
500
1124
  MIT License - see [LICENSE](./LICENSE) file for details.
@@ -503,10 +1127,23 @@ MIT License - see [LICENSE](./LICENSE) file for details.
503
1127
 
504
1128
  Please read [CONTRIBUTING.md](./CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.
505
1129
 
1130
+ ## API Documentation
1131
+
1132
+ Comprehensive API documentation is available in the [docs](./docs) directory:
1133
+
1134
+ - **[API Overview](./docs/index.md)** - Complete API reference
1135
+ - **[Components](./docs/ts-res-ui-components.md)** - All available components and their props
1136
+ - **[Hooks](./docs/ts-res-ui-components.md)** - State management hooks (useViewState, useResolutionState, etc.)
1137
+ - **[Types](./docs/ts-res-ui-components.md)** - TypeScript interfaces and type definitions
1138
+ - **[Tool Namespaces](./docs/ts-res-ui-components.md)** - Organized tool namespaces with view components and utility functions
1139
+
1140
+ The API documentation includes detailed examples, usage patterns, and type information for all public APIs.
1141
+
506
1142
  ## Support
507
1143
 
508
1144
  For questions and support, please:
509
1145
 
510
- 1. Check the [documentation](https://docs.ts-res.dev)
511
- 2. Search [existing issues](https://github.com/fgv/ts-res/issues)
512
- 3. Create a [new issue](https://github.com/fgv/ts-res/issues/new)
1146
+ 1. Check the [API documentation](./docs/index.md) for detailed component usage
1147
+ 2. Review the [ts-res documentation](https://docs.ts-res.dev) for core concepts
1148
+ 3. Search [existing issues](https://github.com/fgv/ts-res/issues)
1149
+ 4. Create a [new issue](https://github.com/fgv/ts-res/issues/new)