@semiont/react-ui 0.2.46 → 0.3.1

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 (215) hide show
  1. package/dist/{PdfAnnotationCanvas.client-COQREPXU.mjs → PdfAnnotationCanvas.client-PVTVPDBQ.mjs} +3 -4
  2. package/dist/PdfAnnotationCanvas.client-PVTVPDBQ.mjs.map +1 -0
  3. package/dist/{ar-7SUXNE34.mjs → ar-5REA6P4J.mjs} +48 -6
  4. package/dist/ar-5REA6P4J.mjs.map +1 -0
  5. package/dist/{bn-XOET3DOI.mjs → bn-YHRYHHPD.mjs} +48 -6
  6. package/dist/bn-YHRYHHPD.mjs.map +1 -0
  7. package/dist/{chunk-3JTO27MH.mjs → chunk-D4GAAQMM.mjs} +2 -9
  8. package/dist/{chunk-Q2KV6Y2J.mjs → chunk-PFQYNPQJ.mjs} +32 -32
  9. package/dist/{chunk-JH7BXE2P.mjs → chunk-VVCCMJS7.mjs} +47 -5
  10. package/dist/chunk-VVCCMJS7.mjs.map +1 -0
  11. package/dist/{cs-X63DXX7L.mjs → cs-JTJXTX2T.mjs} +48 -6
  12. package/dist/cs-JTJXTX2T.mjs.map +1 -0
  13. package/dist/{da-OWTCV57A.mjs → da-MK37SJB6.mjs} +48 -6
  14. package/dist/da-MK37SJB6.mjs.map +1 -0
  15. package/dist/{de-77BMFDVF.mjs → de-LGBCWERA.mjs} +48 -6
  16. package/dist/de-LGBCWERA.mjs.map +1 -0
  17. package/dist/dist-YLEIY3JJ.mjs +547 -0
  18. package/dist/dist-YLEIY3JJ.mjs.map +1 -0
  19. package/dist/{el-FIBNLH2V.mjs → el-FKJMFCWY.mjs} +48 -6
  20. package/dist/el-FKJMFCWY.mjs.map +1 -0
  21. package/dist/{en-XWEPVTB4.mjs → en-AOSMPC2M.mjs} +5 -3
  22. package/dist/{es-726NTS53.mjs → es-LVDPIXWU.mjs} +48 -6
  23. package/dist/es-LVDPIXWU.mjs.map +1 -0
  24. package/dist/{fa-3N4CIWE6.mjs → fa-3VA2PIUD.mjs} +48 -6
  25. package/dist/fa-3VA2PIUD.mjs.map +1 -0
  26. package/dist/{fi-JOM3M7Z4.mjs → fi-3WM75ZLR.mjs} +48 -6
  27. package/dist/fi-3WM75ZLR.mjs.map +1 -0
  28. package/dist/{fr-56QSXS7E.mjs → fr-NK4A72WA.mjs} +48 -6
  29. package/dist/fr-NK4A72WA.mjs.map +1 -0
  30. package/dist/{he-SNAXPJEK.mjs → he-IACZDZMB.mjs} +48 -6
  31. package/dist/he-IACZDZMB.mjs.map +1 -0
  32. package/dist/{hi-CRBRD5TB.mjs → hi-JZ7MGMMS.mjs} +48 -6
  33. package/dist/hi-JZ7MGMMS.mjs.map +1 -0
  34. package/dist/{id-BRCVLICF.mjs → id-P3KDQGNK.mjs} +48 -6
  35. package/dist/id-P3KDQGNK.mjs.map +1 -0
  36. package/dist/index.css +123 -12
  37. package/dist/index.css.map +1 -1
  38. package/dist/index.d.mts +353 -107
  39. package/dist/index.mjs +3139 -1811
  40. package/dist/index.mjs.map +1 -1
  41. package/dist/{it-M2Z27BNB.mjs → it-LQS33SUY.mjs} +48 -6
  42. package/dist/it-LQS33SUY.mjs.map +1 -0
  43. package/dist/{ja-TZUKW7HD.mjs → ja-G4FKZPWD.mjs} +48 -6
  44. package/dist/ja-G4FKZPWD.mjs.map +1 -0
  45. package/dist/{ko-NKBGGOL6.mjs → ko-2XWKQ7BA.mjs} +48 -6
  46. package/dist/ko-2XWKQ7BA.mjs.map +1 -0
  47. package/dist/{magic-string.es-7FJ3LUGB.mjs → magic-string.es-K77I4ZQN.mjs} +2 -2
  48. package/dist/{ms-XFXPN6RX.mjs → ms-2SNONIUD.mjs} +48 -6
  49. package/dist/ms-2SNONIUD.mjs.map +1 -0
  50. package/dist/{nl-MVYXAS5C.mjs → nl-BMZUAJ7J.mjs} +48 -6
  51. package/dist/nl-BMZUAJ7J.mjs.map +1 -0
  52. package/dist/{no-XOLO4JPV.mjs → no-6J3WIZ6L.mjs} +48 -6
  53. package/dist/no-6J3WIZ6L.mjs.map +1 -0
  54. package/dist/{pl-TRWLMMC4.mjs → pl-QQ7DAUVK.mjs} +48 -6
  55. package/dist/pl-QQ7DAUVK.mjs.map +1 -0
  56. package/dist/{pt-M3TE24UI.mjs → pt-MU3GN7MW.mjs} +48 -6
  57. package/dist/pt-MU3GN7MW.mjs.map +1 -0
  58. package/dist/{ro-QBFG2T64.mjs → ro-6GBE72QK.mjs} +48 -6
  59. package/dist/ro-6GBE72QK.mjs.map +1 -0
  60. package/dist/{sv-IUECBXWX.mjs → sv-NQIL7PEM.mjs} +48 -6
  61. package/dist/sv-NQIL7PEM.mjs.map +1 -0
  62. package/dist/test-utils.mjs +16994 -22140
  63. package/dist/test-utils.mjs.map +1 -1
  64. package/dist/{th-US7KIN5Q.mjs → th-6OCNZQBE.mjs} +48 -6
  65. package/dist/th-6OCNZQBE.mjs.map +1 -0
  66. package/dist/{tr-DWJ2FFUK.mjs → tr-XWJ5P3SC.mjs} +48 -6
  67. package/dist/tr-XWJ5P3SC.mjs.map +1 -0
  68. package/dist/{uk-M4ZE4DPZ.mjs → uk-AKSN6DGW.mjs} +48 -6
  69. package/dist/uk-AKSN6DGW.mjs.map +1 -0
  70. package/dist/{vi-FERZNPSH.mjs → vi-23GHQ45M.mjs} +48 -6
  71. package/dist/vi-23GHQ45M.mjs.map +1 -0
  72. package/dist/{zh-3J2I3WYK.mjs → zh-ITT4QBSN.mjs} +48 -6
  73. package/dist/zh-ITT4QBSN.mjs.map +1 -0
  74. package/package.json +18 -14
  75. package/src/components/Button/Button.tsx +23 -25
  76. package/src/components/annotation/AnnotateToolbar.tsx +1 -1
  77. package/src/components/annotation-popups/SharedPopupElements.tsx +5 -7
  78. package/src/components/image-annotation/SvgDrawingCanvas.tsx +3 -4
  79. package/src/components/modals/ConfigureGenerationStep.tsx +190 -0
  80. package/src/components/modals/ConfigureSearchStep.tsx +105 -0
  81. package/src/components/modals/ContextSummary.tsx +202 -0
  82. package/src/components/modals/GatherContextStep.tsx +93 -0
  83. package/src/components/modals/KeyboardShortcutsHelpModal.tsx +4 -6
  84. package/src/components/modals/ProposeEntitiesModal.tsx +4 -6
  85. package/src/components/modals/ReferenceWizardModal.tsx +338 -0
  86. package/src/components/modals/ResourceSearchModal.tsx +4 -6
  87. package/src/components/modals/SearchModal.css +43 -0
  88. package/src/components/modals/SearchModal.tsx +4 -6
  89. package/src/components/modals/SearchResultsStep.tsx +126 -0
  90. package/src/components/pdf-annotation/PdfAnnotationCanvas.tsx +3 -4
  91. package/src/components/pdf-annotation/__tests__/PdfAnnotationCanvas.test.tsx +36 -14
  92. package/src/components/resource/AnnotateView.tsx +4 -4
  93. package/src/components/resource/AnnotationHistory.tsx +2 -2
  94. package/src/components/resource/BrowseView.tsx +4 -4
  95. package/src/components/resource/ResourceViewer.tsx +4 -7
  96. package/src/components/resource/__tests__/AnnotationHistory.test.tsx +16 -16
  97. package/src/components/resource/__tests__/BrowseView.test.tsx +2 -2
  98. package/src/components/resource/__tests__/HistoryEvent.test.tsx +1 -1
  99. package/src/components/resource/__tests__/ResourceViewer.mode-switch.test.tsx +1 -1
  100. package/src/components/resource/panels/AssessmentEntry.tsx +9 -11
  101. package/src/components/resource/panels/CommentEntry.tsx +10 -12
  102. package/src/components/resource/panels/HighlightEntry.tsx +9 -11
  103. package/src/components/resource/panels/ReferenceEntry.tsx +57 -104
  104. package/src/components/resource/panels/ReferencesPanel.css +94 -13
  105. package/src/components/resource/panels/ReferencesPanel.tsx +1 -2
  106. package/src/components/resource/panels/TagEntry.tsx +9 -11
  107. package/src/components/resource/panels/__tests__/AssistSection.test.tsx +7 -7
  108. package/src/components/resource/panels/__tests__/HighlightPanel.annotationProgress.test.tsx +2 -2
  109. package/src/components/resource/panels/__tests__/ReferenceEntry.test.tsx +64 -101
  110. package/src/components/resource/panels/__tests__/StatisticsPanel.test.tsx +1 -1
  111. package/src/components/resource/panels/__tests__/TaggingPanel.test.tsx +3 -3
  112. package/src/components/viewers/ImageViewer.tsx +3 -6
  113. package/src/components/viewers/__tests__/ImageViewer.test.tsx +3 -3
  114. package/src/features/admin-devops/__tests__/AdminDevOpsPage.test.tsx +5 -5
  115. package/src/features/admin-exchange/__tests__/AdminExchangePage.test.tsx +141 -0
  116. package/src/features/admin-exchange/__tests__/ExportCard.test.tsx +41 -0
  117. package/src/features/admin-exchange/__tests__/ImportCard.test.tsx +148 -0
  118. package/src/features/admin-exchange/__tests__/ImportProgress.test.tsx +106 -0
  119. package/src/features/admin-exchange/components/AdminExchangePage.tsx +120 -0
  120. package/src/features/admin-exchange/components/ExportCard.tsx +35 -0
  121. package/src/features/admin-exchange/components/ImportCard.tsx +188 -0
  122. package/src/features/admin-exchange/components/ImportProgress.tsx +86 -0
  123. package/src/features/admin-security/__tests__/AdminSecurityPage.test.tsx +3 -3
  124. package/src/features/moderate-entity-tags/__tests__/EntityTagsPage.test.tsx +2 -2
  125. package/src/features/moderate-recent/__tests__/RecentDocumentsPage.test.tsx +4 -4
  126. package/src/features/moderate-tag-schemas/__tests__/TagSchemasPage.test.tsx +3 -3
  127. package/src/features/moderation-linked-data/__tests__/LinkedDataPage.test.tsx +117 -0
  128. package/src/features/moderation-linked-data/components/LinkedDataPage.tsx +121 -0
  129. package/src/features/resource-compose/__tests__/ResourceComposePage.test.tsx +5 -5
  130. package/src/features/resource-compose/components/ResourceComposePage.tsx +56 -1
  131. package/src/features/resource-discovery/__tests__/ResourceCard.test.tsx +1 -1
  132. package/src/features/resource-discovery/__tests__/ResourceDiscoveryPage.test.tsx +2 -2
  133. package/src/features/resource-viewer/__tests__/AnnotationCreationPending.test.tsx +3 -3
  134. package/src/features/resource-viewer/__tests__/AnnotationDeletionIntegration.test.tsx +11 -10
  135. package/src/features/resource-viewer/__tests__/AnnotationProgressDismissal.test.tsx +2 -2
  136. package/src/features/resource-viewer/__tests__/BindFlowIntegration.test.tsx +22 -115
  137. package/src/features/resource-viewer/__tests__/DetectionFlowBug.test.tsx +3 -3
  138. package/src/features/resource-viewer/__tests__/DetectionFlowIntegration.test.tsx +20 -20
  139. package/src/features/resource-viewer/__tests__/ResourceMutations.test.tsx +7 -7
  140. package/src/features/resource-viewer/__tests__/ResourceViewerPage.test.tsx +5 -21
  141. package/src/features/resource-viewer/__tests__/ToastNotifications.test.tsx +2 -2
  142. package/src/features/resource-viewer/__tests__/YieldFlowIntegration.test.tsx +45 -82
  143. package/src/features/resource-viewer/__tests__/annotation-progress-flow.test.tsx +4 -4
  144. package/src/features/resource-viewer/components/ResourceViewerPage.tsx +146 -72
  145. package/src/integrations/tailwind-plugin.js +3 -3
  146. package/src/styles/core/buttons.css +31 -0
  147. package/src/styles/features/exchange.css +404 -0
  148. package/src/styles/index.css +1 -0
  149. package/translations/ar.json +44 -4
  150. package/translations/bn.json +44 -4
  151. package/translations/cs.json +44 -4
  152. package/translations/da.json +130 -90
  153. package/translations/de.json +124 -84
  154. package/translations/el.json +44 -4
  155. package/translations/en.json +44 -4
  156. package/translations/es.json +44 -4
  157. package/translations/fa.json +44 -4
  158. package/translations/fi.json +70 -30
  159. package/translations/fr.json +44 -4
  160. package/translations/he.json +44 -4
  161. package/translations/hi.json +44 -4
  162. package/translations/id.json +45 -5
  163. package/translations/it.json +64 -24
  164. package/translations/ja.json +45 -5
  165. package/translations/ko.json +44 -4
  166. package/translations/ms.json +45 -5
  167. package/translations/nl.json +43 -3
  168. package/translations/no.json +106 -66
  169. package/translations/pl.json +44 -4
  170. package/translations/pt.json +45 -5
  171. package/translations/ro.json +44 -4
  172. package/translations/sv.json +44 -4
  173. package/translations/th.json +44 -4
  174. package/translations/tr.json +44 -4
  175. package/translations/uk.json +44 -4
  176. package/translations/vi.json +44 -4
  177. package/translations/zh.json +44 -4
  178. package/dist/PdfAnnotationCanvas.client-COQREPXU.mjs.map +0 -1
  179. package/dist/ar-7SUXNE34.mjs.map +0 -1
  180. package/dist/bn-XOET3DOI.mjs.map +0 -1
  181. package/dist/chunk-JH7BXE2P.mjs.map +0 -1
  182. package/dist/cs-X63DXX7L.mjs.map +0 -1
  183. package/dist/da-OWTCV57A.mjs.map +0 -1
  184. package/dist/de-77BMFDVF.mjs.map +0 -1
  185. package/dist/el-FIBNLH2V.mjs.map +0 -1
  186. package/dist/es-726NTS53.mjs.map +0 -1
  187. package/dist/fa-3N4CIWE6.mjs.map +0 -1
  188. package/dist/fi-JOM3M7Z4.mjs.map +0 -1
  189. package/dist/fr-56QSXS7E.mjs.map +0 -1
  190. package/dist/he-SNAXPJEK.mjs.map +0 -1
  191. package/dist/hi-CRBRD5TB.mjs.map +0 -1
  192. package/dist/id-BRCVLICF.mjs.map +0 -1
  193. package/dist/it-M2Z27BNB.mjs.map +0 -1
  194. package/dist/ja-TZUKW7HD.mjs.map +0 -1
  195. package/dist/ko-NKBGGOL6.mjs.map +0 -1
  196. package/dist/ms-XFXPN6RX.mjs.map +0 -1
  197. package/dist/nl-MVYXAS5C.mjs.map +0 -1
  198. package/dist/no-XOLO4JPV.mjs.map +0 -1
  199. package/dist/pl-TRWLMMC4.mjs.map +0 -1
  200. package/dist/pt-M3TE24UI.mjs.map +0 -1
  201. package/dist/ro-QBFG2T64.mjs.map +0 -1
  202. package/dist/sv-IUECBXWX.mjs.map +0 -1
  203. package/dist/th-US7KIN5Q.mjs.map +0 -1
  204. package/dist/tr-DWJ2FFUK.mjs.map +0 -1
  205. package/dist/uk-M4ZE4DPZ.mjs.map +0 -1
  206. package/dist/vi-FERZNPSH.mjs.map +0 -1
  207. package/dist/zh-3J2I3WYK.mjs.map +0 -1
  208. package/src/examples/ButtonUsageExample.tsx +0 -242
  209. package/src/examples/button-css-modules.module.css +0 -164
  210. package/src/examples/button-styled-components.tsx +0 -215
  211. package/src/examples/button-tailwind.css +0 -51
  212. /package/dist/{chunk-3JTO27MH.mjs.map → chunk-D4GAAQMM.mjs.map} +0 -0
  213. /package/dist/{chunk-Q2KV6Y2J.mjs.map → chunk-PFQYNPQJ.mjs.map} +0 -0
  214. /package/dist/{en-XWEPVTB4.mjs.map → en-AOSMPC2M.mjs.map} +0 -0
  215. /package/dist/{magic-string.es-7FJ3LUGB.mjs.map → magic-string.es-K77I4ZQN.mjs.map} +0 -0
@@ -27,8 +27,8 @@ import { ApiClientProvider } from '../../../contexts/ApiClientContext';
27
27
  import { AuthTokenProvider } from '../../../contexts/AuthTokenContext';
28
28
  import { useBindFlow } from '../../../hooks/useBindFlow';
29
29
  import { SSEClient } from '@semiont/api-client';
30
- import type { ResourceUri, AnnotationUri } from '@semiont/core';
31
- import { resourceUri, annotationUri } from '@semiont/core';
30
+ import type { AnnotationId, ResourceId } from '@semiont/core';
31
+ import { resourceId, annotationId } from '@semiont/core';
32
32
  import type { Emitter } from 'mitt';
33
33
  import type { EventMap } from '@semiont/core';
34
34
 
@@ -76,38 +76,17 @@ describe('Generation Flow - Feature Integration', () => {
76
76
  vi.restoreAllMocks();
77
77
  });
78
78
 
79
- it('should open modal when yield:modal-open event is emitted', async () => {
80
- const testResourceUri = resourceUri('http://localhost:4000/resources/test-resource');
81
- const testAnnotationUri = annotationUri('http://localhost:4000/resources/test-resource/annotations/test-annotation');
82
-
83
- const { emitModalOpen } = renderYieldFlow(
84
- testResourceUri
85
- );
86
-
87
- // Emit modal open event
88
- act(() => {
89
- emitModalOpen(testAnnotationUri, testResourceUri, 'Test Reference');
90
- });
91
-
92
- // Verify modal state updated
93
- await waitFor(() => {
94
- expect(screen.getByTestId('modal-open')).toHaveTextContent('true');
95
- expect(screen.getByTestId('reference-id')).toHaveTextContent(testAnnotationUri);
96
- expect(screen.getByTestId('default-title')).toHaveTextContent('Test Reference');
97
- });
98
- });
99
-
100
79
  it('should call yieldResourceFromAnnotation exactly ONCE when generation starts', async () => {
101
- const testResourceUri = resourceUri('http://localhost:4000/resources/test-resource');
102
- const testAnnotationUri = annotationUri('http://localhost:4000/resources/test-resource/annotations/test-annotation');
80
+ const testResourceId = resourceId('test-resource');
81
+ const testAnnotationId = annotationId('test-annotation');
103
82
 
104
83
  const { emitGenerationStart, getEventBus } = renderYieldFlow(
105
- testResourceUri
84
+ testResourceId
106
85
  );
107
86
 
108
87
  // Trigger generation with full options
109
88
  act(() => {
110
- emitGenerationStart(testAnnotationUri, testResourceUri, {
89
+ emitGenerationStart(testAnnotationId, testResourceId, {
111
90
  title: 'Generated Document',
112
91
  prompt: 'Create a comprehensive document',
113
92
  language: 'en',
@@ -125,10 +104,10 @@ describe('Generation Flow - Feature Integration', () => {
125
104
  expect(generateResourceSpy).toHaveBeenCalledTimes(1);
126
105
  });
127
106
 
128
- // Verify correct parameters
107
+ // Verify correct parameters — resourceId and annotationId are now bare IDs
129
108
  expect(generateResourceSpy).toHaveBeenCalledWith(
130
- testResourceUri,
131
- testAnnotationUri,
109
+ testResourceId,
110
+ testAnnotationId,
132
111
  {
133
112
  title: 'Generated Document',
134
113
  prompt: 'Create a comprehensive document',
@@ -145,16 +124,16 @@ describe('Generation Flow - Feature Integration', () => {
145
124
  });
146
125
 
147
126
  it('should propagate SSE progress events to useYieldProgress state', async () => {
148
- const testResourceUri = resourceUri('http://localhost:4000/resources/test-resource');
149
- const testAnnotationUri = annotationUri('http://localhost:4000/resources/test-resource/annotations/test-annotation');
127
+ const testResourceId = resourceId('test-resource');
128
+ const testAnnotationId = annotationId('test-annotation');
150
129
 
151
130
  const { emitGenerationStart, getEventBus } = renderYieldFlow(
152
- testResourceUri
131
+ testResourceId
153
132
  );
154
133
 
155
134
  // Start generation
156
135
  act(() => {
157
- emitGenerationStart(testAnnotationUri, testResourceUri, {
136
+ emitGenerationStart(testAnnotationId, testResourceId, {
158
137
  title: 'Test Doc',
159
138
  context: { sourceText: 'test' },
160
139
  });
@@ -182,16 +161,16 @@ describe('Generation Flow - Feature Integration', () => {
182
161
  });
183
162
 
184
163
  it('should handle multiple progress updates correctly', async () => {
185
- const testResourceUri = resourceUri('http://localhost:4000/resources/test-resource');
186
- const testAnnotationUri = annotationUri('http://localhost:4000/resources/test-resource/annotations/test-annotation');
164
+ const testResourceId = resourceId('test-resource');
165
+ const testAnnotationId = annotationId('test-annotation');
187
166
 
188
167
  const { emitGenerationStart, getEventBus } = renderYieldFlow(
189
- testResourceUri
168
+ testResourceId
190
169
  );
191
170
 
192
171
  // Start generation
193
172
  act(() => {
194
- emitGenerationStart(testAnnotationUri, testResourceUri, {
173
+ emitGenerationStart(testAnnotationId, testResourceId, {
195
174
  title: 'Test',
196
175
  context: { sourceText: 'test' },
197
176
  });
@@ -231,7 +210,7 @@ describe('Generation Flow - Feature Integration', () => {
231
210
  act(() => {
232
211
  getEventBus().get('yield:finished').next({
233
212
  status: 'complete',
234
- referenceId: testAnnotationUri,
213
+ referenceId: testAnnotationId,
235
214
  message: 'Document created successfully',
236
215
  percentage: 100,
237
216
  resourceName: 'Generated Document',
@@ -245,16 +224,16 @@ describe('Generation Flow - Feature Integration', () => {
245
224
  });
246
225
 
247
226
  it('should show success toast on generation complete', async () => {
248
- const testResourceUri = resourceUri('http://localhost:4000/resources/test-resource');
249
- const testAnnotationUri = annotationUri('http://localhost:4000/resources/test-resource/annotations/test-annotation');
227
+ const testResourceId = resourceId('test-resource');
228
+ const testAnnotationId = annotationId('test-annotation');
250
229
 
251
230
  const { emitGenerationStart, getEventBus } = renderYieldFlow(
252
- testResourceUri
231
+ testResourceId
253
232
  );
254
233
 
255
234
  // Start generation
256
235
  act(() => {
257
- emitGenerationStart(testAnnotationUri, testResourceUri, {
236
+ emitGenerationStart(testAnnotationId, testResourceId, {
258
237
  title: 'Test',
259
238
  context: { sourceText: 'test' },
260
239
  });
@@ -277,7 +256,7 @@ describe('Generation Flow - Feature Integration', () => {
277
256
  act(() => {
278
257
  getEventBus().get('yield:finished').next({
279
258
  status: 'complete',
280
- referenceId: testAnnotationUri,
259
+ referenceId: testAnnotationId,
281
260
  resourceName: 'Generated Document',
282
261
  percentage: 100,
283
262
  });
@@ -288,16 +267,16 @@ describe('Generation Flow - Feature Integration', () => {
288
267
  });
289
268
 
290
269
  it('should clear progress on generation failure', async () => {
291
- const testResourceUri = resourceUri('http://localhost:4000/resources/test-resource');
292
- const testAnnotationUri = annotationUri('http://localhost:4000/resources/test-resource/annotations/test-annotation');
270
+ const testResourceId = resourceId('test-resource');
271
+ const testAnnotationId = annotationId('test-annotation');
293
272
 
294
273
  const { emitGenerationStart, getEventBus } = renderYieldFlow(
295
- testResourceUri
274
+ testResourceId
296
275
  );
297
276
 
298
277
  // Start generation
299
278
  act(() => {
300
- emitGenerationStart(testAnnotationUri, testResourceUri, {
279
+ emitGenerationStart(testAnnotationId, testResourceId, {
301
280
  title: 'Test',
302
281
  context: { sourceText: 'test' },
303
282
  });
@@ -328,11 +307,11 @@ describe('Generation Flow - Feature Integration', () => {
328
307
  });
329
308
 
330
309
  it('should only call API once even with multiple event listeners', async () => {
331
- const testResourceUri = resourceUri('http://localhost:4000/resources/test-resource');
332
- const testAnnotationUri = annotationUri('http://localhost:4000/resources/test-resource/annotations/test-annotation');
310
+ const testResourceId = resourceId('test-resource');
311
+ const testAnnotationId = annotationId('test-annotation');
333
312
 
334
313
  const { emitGenerationStart, getEventBus } = renderYieldFlow(
335
- testResourceUri
314
+ testResourceId
336
315
  );
337
316
 
338
317
  // Add an additional event listener (simulating multiple subscribers)
@@ -341,7 +320,7 @@ describe('Generation Flow - Feature Integration', () => {
341
320
 
342
321
  // Trigger generation
343
322
  act(() => {
344
- emitGenerationStart(testAnnotationUri, testResourceUri, {
323
+ emitGenerationStart(testAnnotationId, testResourceId, {
345
324
  title: 'Test',
346
325
  context: { sourceText: 'test' },
347
326
  });
@@ -362,16 +341,16 @@ describe('Generation Flow - Feature Integration', () => {
362
341
  });
363
342
 
364
343
  it('should forward final chunk as progress before emitting complete', async () => {
365
- const testResourceUri = resourceUri('http://localhost:4000/resources/test-resource');
366
- const testAnnotationUri = annotationUri('http://localhost:4000/resources/test-resource/annotations/test-annotation');
344
+ const testResourceId = resourceId('test-resource');
345
+ const testAnnotationId = annotationId('test-annotation');
367
346
 
368
347
  const { emitGenerationStart, getEventBus } = renderYieldFlow(
369
- testResourceUri
348
+ testResourceId
370
349
  );
371
350
 
372
351
  // Start generation
373
352
  act(() => {
374
- emitGenerationStart(testAnnotationUri, testResourceUri, {
353
+ emitGenerationStart(testAnnotationId, testResourceId, {
375
354
  title: 'Test',
376
355
  context: { sourceText: 'test' },
377
356
  });
@@ -385,7 +364,7 @@ describe('Generation Flow - Feature Integration', () => {
385
364
  act(() => {
386
365
  getEventBus().get('yield:finished').next({
387
366
  status: 'complete',
388
- referenceId: testAnnotationUri,
367
+ referenceId: testAnnotationId,
389
368
  message: 'Document created: My Document',
390
369
  resourceName: 'My Document',
391
370
  percentage: 100,
@@ -405,7 +384,7 @@ describe('Generation Flow - Feature Integration', () => {
405
384
  * Returns methods to interact with the rendered component
406
385
  */
407
386
  function renderYieldFlow(
408
- testResourceUri: ResourceUri
387
+ testResourceId: ResourceId
409
388
  ) {
410
389
  let eventBusInstance: Emitter<EventMap>;
411
390
 
@@ -414,7 +393,7 @@ function renderYieldFlow(
414
393
  eventBusInstance = useEventBus();
415
394
 
416
395
  // Set up resolution flow (resolve:update-body, resolve:link)
417
- useBindFlow(testResourceUri);
396
+ useBindFlow(testResourceId);
418
397
 
419
398
  return null;
420
399
  }
@@ -422,23 +401,18 @@ function renderYieldFlow(
422
401
  // Test harness component that uses the hook
423
402
  function YieldFlowTestHarness() {
424
403
  const {
404
+ isGenerating,
425
405
  generationProgress,
426
- generationModalOpen,
427
- generationReferenceId,
428
- generationDefaultTitle,
429
406
  } = useYieldFlow(
430
407
  'en',
431
- testResourceUri.split('/resources/')[1] || 'test-resource',
408
+ testResourceId,
432
409
  vi.fn()
433
410
  );
434
411
 
435
412
  return (
436
413
  <div>
437
- <div data-testid="modal-open">{generationModalOpen ? 'true' : 'false'}</div>
438
- <div data-testid="reference-id">{generationReferenceId || 'none'}</div>
439
- <div data-testid="default-title">{generationDefaultTitle || 'none'}</div>
440
414
  <div data-testid="is-generating">
441
- {generationProgress ? 'true' : 'false'}
415
+ {isGenerating ? 'true' : 'false'}
442
416
  </div>
443
417
  <div data-testid="progress">
444
418
  {generationProgress?.message || 'No progress'}
@@ -459,20 +433,9 @@ function renderYieldFlow(
459
433
  );
460
434
 
461
435
  return {
462
- emitModalOpen: (
463
- annotationUri: AnnotationUri,
464
- resourceUri: ResourceUri,
465
- defaultTitle: string
466
- ) => {
467
- eventBusInstance.get('yield:modal-open').next({
468
- annotationUri,
469
- resourceUri,
470
- defaultTitle,
471
- });
472
- },
473
436
  emitGenerationStart: (
474
- annotationUri: AnnotationUri,
475
- resourceUri: ResourceUri,
437
+ aId: AnnotationId,
438
+ rId: ResourceId,
476
439
  options: {
477
440
  title: string;
478
441
  prompt?: string;
@@ -483,8 +446,8 @@ function renderYieldFlow(
483
446
  }
484
447
  ) => {
485
448
  eventBusInstance.get('yield:request').next({
486
- annotationUri,
487
- resourceUri,
449
+ annotationId: aId,
450
+ resourceId: rId,
488
451
  options,
489
452
  });
490
453
  },
@@ -180,7 +180,7 @@ describe('Detection Progress Flow Integration (Layer 3)', () => {
180
180
  expect(screen.queryByText(/Analyzing/)).not.toBeInTheDocument();
181
181
 
182
182
  // Click annotate button
183
- const annotateButton = screen.getByRole('button', { name: /✨ Annotate/ });
183
+ const annotateButton = screen.getByRole('button', { name: /✨\s*Annotate/ });
184
184
  await user.click(annotateButton);
185
185
 
186
186
  // Simulate SSE progress chunk #1: Starting
@@ -244,7 +244,7 @@ describe('Detection Progress Flow Integration (Layer 3)', () => {
244
244
  renderDetectionFlow();
245
245
 
246
246
  // Click annotate button
247
- const annotateButton = screen.getByRole('button', { name: /✨ Annotate/ });
247
+ const annotateButton = screen.getByRole('button', { name: /✨\s*Annotate/ });
248
248
  await user.click(annotateButton);
249
249
 
250
250
  // Simulate initial progress
@@ -284,7 +284,7 @@ describe('Detection Progress Flow Integration (Layer 3)', () => {
284
284
 
285
285
  renderDetectionFlow();
286
286
 
287
- const annotateButton = screen.getByRole('button', { name: /✨ Annotate/ });
287
+ const annotateButton = screen.getByRole('button', { name: /✨\s*Annotate/ });
288
288
  await user.click(annotateButton);
289
289
 
290
290
  // Simulate progress with request parameters
@@ -310,7 +310,7 @@ describe('Detection Progress Flow Integration (Layer 3)', () => {
310
310
 
311
311
  renderDetectionFlow();
312
312
 
313
- const annotateButton = screen.getByRole('button', { name: /✨ Annotate/ });
313
+ const annotateButton = screen.getByRole('button', { name: /✨\s*Annotate/ });
314
314
  await user.click(annotateButton);
315
315
 
316
316
  // Show progress
@@ -7,10 +7,9 @@
7
7
 
8
8
  import React, { useState, useEffect, useCallback, useMemo } from 'react';
9
9
  import { useQueryClient } from '@tanstack/react-query';
10
- import type { components, ResourceUri, ResourceEvent } from '@semiont/core';
11
- import { resourceAnnotationUri } from '@semiont/core';
10
+ import type { components, ResourceId, ResourceEvent, GatheredContext } from '@semiont/core';
11
+ import { annotationId } from '@semiont/core';
12
12
  import { getLanguage, getPrimaryRepresentation, getPrimaryMediaType } from '@semiont/api-client';
13
- import { uriToAnnotationId } from '@semiont/core';
14
13
  import { ANNOTATORS } from '@semiont/react-ui';
15
14
  import { ErrorBoundary } from '@semiont/react-ui';
16
15
  import { AnnotationHistory } from '@semiont/react-ui';
@@ -20,7 +19,6 @@ import { CollaborationPanel } from '@semiont/react-ui';
20
19
  import { JsonLdPanel } from '@semiont/react-ui';
21
20
  import { Toolbar } from '@semiont/react-ui';
22
21
  import { useResourceLoadingAnnouncements } from '@semiont/react-ui';
23
- import type { GenerationOptions } from '@semiont/react-ui';
24
22
  import { ResourceViewer } from '@semiont/react-ui';
25
23
  import { QUERY_KEYS } from '../../../lib/query-keys';
26
24
  import { useResources, useEntityTypes } from '../../../lib/api-hooks';
@@ -43,6 +41,9 @@ import { useBeckonFlow } from '../../../hooks/useBeckonFlow';
43
41
  import { usePanelBrowse } from '../../../hooks/usePanelBrowse';
44
42
  import { useYieldFlow } from '../../../hooks/useYieldFlow';
45
43
  import { useContextGatherFlow } from '../../../hooks/useContextGatherFlow';
44
+ import { useTranslations } from '../../../contexts/TranslationContext';
45
+ import { ReferenceWizardModal } from '../../../components/modals/ReferenceWizardModal';
46
+ import type { GenerationConfig } from '../../../components/modals/ConfigureGenerationStep';
46
47
 
47
48
  type SemiontResource = components['schemas']['ResourceDescriptor'];
48
49
  type Annotation = components['schemas']['Annotation'];
@@ -56,7 +57,7 @@ export interface ResourceViewerPageProps {
56
57
  /**
57
58
  * Resource URI
58
59
  */
59
- rUri: ResourceUri;
60
+ rUri: ResourceId;
60
61
 
61
62
  /**
62
63
  * Current locale
@@ -77,8 +78,6 @@ export interface ResourceViewerPageProps {
77
78
  * Component dependencies - passed from framework layer
78
79
  */
79
80
  ToolbarPanels: React.ComponentType<any>;
80
- SearchResourcesModal: React.ComponentType<any>;
81
- GenerationConfigModal: React.ComponentType<any>;
82
81
 
83
82
  /**
84
83
  * Callback to refetch document from parent
@@ -120,10 +119,11 @@ export function ResourceViewerPage({
120
119
  Link,
121
120
  routes,
122
121
  ToolbarPanels,
123
- SearchResourcesModal,
124
- GenerationConfigModal,
125
122
  refetchDocument,
126
123
  }: ResourceViewerPageProps) {
124
+ // Translations
125
+ const tw = useTranslations('ReferenceWizard');
126
+
127
127
  // Get unified event bus for subscribing to UI events
128
128
  const eventBus = useEventBus();
129
129
  const client = useApiClient();
@@ -160,16 +160,85 @@ export function ResourceViewerPage({
160
160
  const { hoveredAnnotationId } = useBeckonFlow();
161
161
  const { assistingMotivation, progress, pendingAnnotation } = useMarkFlow(rUri);
162
162
  const { activePanel, scrollToAnnotationId, panelInitialTab, onScrollCompleted } = usePanelBrowse();
163
- const { searchModalOpen, pendingReferenceId, onCloseSearchModal } = useBindFlow(rUri);
163
+ useBindFlow(rUri);
164
164
  const {
165
165
  generationProgress,
166
- generationModalOpen,
167
- generationReferenceId,
168
- generationDefaultTitle,
169
166
  onGenerateDocument,
170
- onCloseGenerationModal,
171
- } = useYieldFlow(locale, rUri.split('/').pop() || '', clearNewAnnotationId);
172
- const { gatherContext, gatherLoading, gatherError } = useContextGatherFlow(eventBus, { client, resourceUri: rUri });
167
+ } = useYieldFlow(locale, rUri, clearNewAnnotationId);
168
+ const { gatherContext, gatherLoading, gatherError } = useContextGatherFlow(eventBus, { client, resourceId: rUri });
169
+
170
+ // Wizard state — driven by bind:initiate from ReferenceEntry
171
+ const [wizardOpen, setWizardOpen] = useState(false);
172
+ const [wizardAnnotationId, setWizardAnnotationId] = useState<string | null>(null);
173
+ const [wizardResourceId, setWizardResourceId] = useState<string | null>(null);
174
+ const [wizardDefaultTitle, setWizardDefaultTitle] = useState('');
175
+ const [wizardEntityTypes, setWizardEntityTypes] = useState<string[]>([]);
176
+
177
+ useEffect(() => {
178
+ const subscription = eventBus.get('bind:initiate').subscribe((event) => {
179
+ setWizardAnnotationId(event.annotationId);
180
+ setWizardResourceId(event.resourceId);
181
+ setWizardDefaultTitle(event.defaultTitle);
182
+ setWizardEntityTypes(event.entityTypes);
183
+ setWizardOpen(true);
184
+
185
+ // Trigger context gathering
186
+ eventBus.get('gather:requested').next({ annotationId: event.annotationId, resourceId: event.resourceId });
187
+ });
188
+ return () => subscription.unsubscribe();
189
+ }, [eventBus]);
190
+
191
+ const handleWizardClose = useCallback(() => {
192
+ setWizardOpen(false);
193
+ }, []);
194
+
195
+ const handleWizardGenerateSubmit = useCallback((referenceId: string, config: GenerationConfig) => {
196
+ onGenerateDocument(referenceId, {
197
+ title: config.title,
198
+ prompt: config.prompt,
199
+ language: config.language,
200
+ temperature: config.temperature,
201
+ maxTokens: config.maxTokens,
202
+ context: config.context,
203
+ });
204
+ }, [onGenerateDocument]);
205
+
206
+ const handleWizardLinkResource = useCallback((referenceId: string, targetResourceId: string) => {
207
+ eventBus.get('bind:update-body').next({
208
+ annotationId: annotationId(referenceId),
209
+ resourceId: rUri,
210
+ operations: [{
211
+ op: 'add',
212
+ item: {
213
+ type: 'SpecificResource' as const,
214
+ source: targetResourceId,
215
+ purpose: 'linking' as const,
216
+ },
217
+ }],
218
+ });
219
+ showSuccess('Reference linked successfully');
220
+ }, [rUri, showSuccess]); // eventBus is stable singleton
221
+
222
+ const handleWizardComposeNavigate = useCallback((
223
+ context: GatheredContext,
224
+ annId: string,
225
+ resId: string,
226
+ title: string,
227
+ entTypes: string[],
228
+ ) => {
229
+ // Store context in sessionStorage for the compose page
230
+ sessionStorage.setItem(`gather-context:${annId}`, JSON.stringify(context));
231
+ const params = new URLSearchParams({
232
+ annotationUri: annId,
233
+ sourceDocumentId: resId,
234
+ name: title,
235
+ entityTypes: entTypes.join(','),
236
+ });
237
+ eventBus.get('browse:router-push').next({
238
+ path: `/know/compose?${params.toString()}`,
239
+ reason: 'compose-from-wizard',
240
+ });
241
+ }, []); // eventBus is stable singleton
173
242
 
174
243
  // Debounced invalidation for real-time events
175
244
  const debouncedInvalidateAnnotations = useDebouncedCallback(
@@ -183,11 +252,10 @@ export function ResourceViewerPage({
183
252
  // Add resource to open tabs when it loads
184
253
  useEffect(() => {
185
254
  if (resource && rUri) {
186
- const resourceIdSegment = rUri.split('/').pop() || '';
187
255
  const mediaType = getPrimaryMediaType(resource);
188
- addResource(resourceIdSegment, resource.name, mediaType || undefined);
256
+ addResource(rUri, resource.name, mediaType || undefined);
189
257
  if (typeof localStorage !== 'undefined') {
190
- localStorage.setItem('lastViewedDocumentId', resourceIdSegment);
258
+ localStorage.setItem('lastViewedDocumentId', rUri);
191
259
  }
192
260
  }
193
261
  }, [resource, rUri, addResource]);
@@ -213,8 +281,7 @@ export function ResourceViewerPage({
213
281
  return {
214
282
  ...old,
215
283
  annotations: old.annotations.map((annotation: any) => {
216
- const annotationIdSegment = uriToAnnotationId(annotation.id);
217
- if (annotationIdSegment === event.payload.annotationId) {
284
+ if (annotation.id === event.payload.annotationId) {
218
285
  let bodyArray = Array.isArray(annotation.body) ? [...annotation.body] : [];
219
286
 
220
287
  for (const op of event.payload.operations || []) {
@@ -283,7 +350,7 @@ export function ResourceViewerPage({
283
350
  // Event handlers extracted to useCallback (tenet: no inline handlers in useEventSubscriptions)
284
351
  const handleResourceArchive = useCallback(async () => {
285
352
  try {
286
- await updateMutation.mutateAsync({ rUri, data: { archived: true } });
353
+ await updateMutation.mutateAsync({ id: rUri, data: { archived: true } });
287
354
  await refetchDocument();
288
355
  } catch (err) {
289
356
  console.error('Failed to archive document:', err);
@@ -293,7 +360,7 @@ export function ResourceViewerPage({
293
360
 
294
361
  const handleResourceUnarchive = useCallback(async () => {
295
362
  try {
296
- await updateMutation.mutateAsync({ rUri, data: { archived: false } });
363
+ await updateMutation.mutateAsync({ id: rUri, data: { archived: false } });
297
364
  await refetchDocument();
298
365
  } catch (err) {
299
366
  console.error('Failed to unarchive document:', err);
@@ -544,7 +611,7 @@ export function ResourceViewerPage({
544
611
  generatingReferenceId={generationProgress?.referenceId ?? null}
545
612
  referencedBy={referencedBy}
546
613
  referencedByLoading={referencedByLoading}
547
- resourceId={rUri.split('/').pop() || ''}
614
+ resourceId={rUri}
548
615
  scrollToAnnotationId={scrollToAnnotationId}
549
616
  hoveredAnnotationId={hoveredAnnotationId}
550
617
  onScrollCompleted={onScrollCompleted}
@@ -601,57 +668,64 @@ export function ResourceViewerPage({
601
668
  </div>
602
669
  </div>
603
670
 
604
- {/* Search Resources Modal */}
605
- <SearchResourcesModal
606
- isOpen={searchModalOpen}
607
- onClose={onCloseSearchModal}
608
- onSelect={async (documentId: string) => {
609
- if (pendingReferenceId) {
610
- try {
611
- const annotationIdShort = pendingReferenceId.split('/').pop();
612
- if (!annotationIdShort) {
613
- throw new Error('Invalid reference ID');
614
- }
615
-
616
- const resourceIdSegment = rUri.split('/').pop() || '';
617
- const nestedUri = `${window.location.origin}/resources/${resourceIdSegment}/annotations/${annotationIdShort}`;
618
-
619
- eventBus.get('bind:update-body').next({
620
- annotationUri: resourceAnnotationUri(nestedUri),
621
- resourceId: resourceIdSegment,
622
- operations: [{
623
- op: 'add',
624
- item: {
625
- type: 'SpecificResource' as const,
626
- source: documentId,
627
- purpose: 'linking' as const,
628
- },
629
- }],
630
- });
631
- showSuccess('Reference linked successfully');
632
- // Cache invalidation now handled by mark:body-updated event
633
- onCloseSearchModal();
634
- } catch (error) {
635
- console.error('Failed to link reference:', error);
636
- showError('Failed to link reference');
637
- }
638
- }
639
- }}
640
- />
641
-
642
- {/* Generation Config Modal */}
643
- <GenerationConfigModal
644
- isOpen={generationModalOpen}
645
- onClose={onCloseGenerationModal}
646
- onGenerate={(options: GenerationOptions) => {
647
- if (generationReferenceId) {
648
- onGenerateDocument(generationReferenceId, options);
649
- }
650
- }}
651
- defaultTitle={generationDefaultTitle}
671
+ {/* Reference Resolution Wizard */}
672
+ <ReferenceWizardModal
673
+ isOpen={wizardOpen}
674
+ onClose={handleWizardClose}
675
+ annotationId={wizardAnnotationId}
676
+ resourceId={wizardResourceId}
677
+ defaultTitle={wizardDefaultTitle}
678
+ entityTypes={wizardEntityTypes}
679
+ locale={locale}
652
680
  context={gatherContext}
653
681
  contextLoading={gatherLoading}
654
682
  contextError={gatherError}
683
+ eventBus={eventBus}
684
+ onGenerateSubmit={handleWizardGenerateSubmit}
685
+ onLinkResource={handleWizardLinkResource}
686
+ onComposeNavigate={handleWizardComposeNavigate}
687
+ translations={{
688
+ gatherTitle: tw('gatherTitle'),
689
+ configureGenerationTitle: tw('configureGenerationTitle'),
690
+ configureSearchTitle: tw('configureSearchTitle'),
691
+ searchResultsTitle: tw('searchResultsTitle'),
692
+ annotationLabel: tw('annotationLabel'),
693
+ sourceResourceLabel: tw('sourceResourceLabel'),
694
+ motivationLabel: tw('motivationLabel'),
695
+ sourceContextLabel: tw('sourceContextLabel'),
696
+ entityTypesLabel: tw('entityTypesLabel'),
697
+ graphContextLabel: tw('graphContextLabel'),
698
+ connectionsLabel: tw('connectionsLabel'),
699
+ citedByLabel: tw('citedByLabel'),
700
+ siblingTypesLabel: tw('siblingTypesLabel'),
701
+ userHintLabel: tw('userHintLabel'),
702
+ userHintPlaceholder: tw('userHintPlaceholder'),
703
+ loadingContext: tw('loadingContext'),
704
+ failedContext: tw('failedContext'),
705
+ cancel: tw('cancel'),
706
+ search: tw('search'),
707
+ searching: tw('searching'),
708
+ generate: tw('generate'),
709
+ compose: tw('compose'),
710
+ back: tw('back'),
711
+ link: tw('link'),
712
+ score: tw('score'),
713
+ noResults: tw('noResults'),
714
+ resourceTitle: tw('resourceTitle'),
715
+ resourceTitlePlaceholder: tw('resourceTitlePlaceholder'),
716
+ additionalInstructions: tw('additionalInstructions'),
717
+ additionalInstructionsPlaceholder: tw('additionalInstructionsPlaceholder'),
718
+ language: tw('language'),
719
+ languageHelp: tw('languageHelp'),
720
+ creativity: tw('creativity'),
721
+ creativityFocused: tw('creativityFocused'),
722
+ creativityCreative: tw('creativityCreative'),
723
+ maxLength: tw('maxLength'),
724
+ maxLengthHelp: tw('maxLengthHelp'),
725
+ maxResults: tw('maxResults'),
726
+ semanticScoring: tw('semanticScoring'),
727
+ semanticScoringHelp: tw('semanticScoringHelp'),
728
+ }}
655
729
  />
656
730
  </div>
657
731
  );
@@ -23,7 +23,7 @@ module.exports = plugin(function({ addBase, addComponents, addUtilities, theme }
23
23
  '.semiont-button': {
24
24
  '@apply relative inline-flex items-center justify-center': {},
25
25
  '@apply font-medium transition-all duration-200': {},
26
- '@apply focus:outline-none focus:ring-2 focus:ring-offset-2': {},
26
+ '@apply focus:outline-hidden focus:ring-2 focus:ring-offset-2': {},
27
27
  '@apply disabled:opacity-50 disabled:cursor-not-allowed': {},
28
28
  },
29
29
 
@@ -56,10 +56,10 @@ module.exports = plugin(function({ addBase, addComponents, addUtilities, theme }
56
56
 
57
57
  // Button sizes
58
58
  '.semiont-button[data-size="xs"]': {
59
- '@apply px-2 py-1 text-xs rounded min-h-[1.75rem]': {},
59
+ '@apply px-2 py-1 text-xs rounded-sm min-h-[1.75rem]': {},
60
60
  },
61
61
  '.semiont-button[data-size="sm"]': {
62
- '@apply px-3 py-1.5 text-sm rounded min-h-[2rem]': {},
62
+ '@apply px-3 py-1.5 text-sm rounded-sm min-h-[2rem]': {},
63
63
  },
64
64
  '.semiont-button[data-size="md"]': {
65
65
  '@apply px-4 py-2 text-base rounded-md min-h-[2.5rem]': {},